简体   繁体   中英

F# constructor constraint

Whilst attempting to learn the use of constructor constraints , I was hoping that something like the following was possible.

type Foo<'T when 'T : (new : int -> 'T)> = {Bar: 'T}

But this does not compile, simply returning the error

'new' constraints must take one argument of type 'unit' and return the constructed type

It seems as though the constraint should be called "parameterless constructor constraint" because I cant get any other form beyond this to compile.

type Foo<'T when 'T : (new : unit-> 'T)> = {Bar: 'T}

Can a constructor constraint be used to constrain the generic types constructor to have a specific signature other than unit ?

As noted in the comments, .NET support for constraints is limited and only supports (i) paremeter-less constructors and (ii) implementation of an interface.

F# follows the same restructions for ordinary generic type parameters, but it also has statically resolved type parameters written as ^T , which can have more expressive constraints. Those are not compiled to .NET constraints, but instead, are erased during the compilation, so there are other constraints on those.

An example akin to what you have using static memnber constraints would look something like this:

type Foo<'T> = 
  { Bar : 'T }
  static member inline Demo< ^S when ^S : (static member Create : int -> ^S)>() = 
    { Bar = (^S : (static member Create : int -> ^S) (10)) }

The constrains need to be on an inline member (or inline function), so I'm defining a generic type Foo<'T> which has a static member Demo that can be called with any type that has a Create method taking an int. For example:

type Sample(n:int) =
  member x.N = n
  static member Create(n:int) = Sample(n)

We can now call Foo.Demo with Sample as the type argument and we get Foo<Sample> back, created using 10 as the initialization value:

let f = Foo<_>.Demo<Sample>()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM