F#构造函数约束

时间:2020-08-08 01:31:27

标签: f#

在尝试学习constructor constraints的使用时,我希望可能会发生以下类似情况。

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

但这不会编译,只是返回错误

“新”约束必须采用类型为“ unit”的一个参数并返回构造的类型

该约束似乎应该称为“无参数构造函数约束”,因为除此以外,我无法获得其他任何形式的编译。

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

构造函数约束可用于约束泛型类型构造函数以具有unit以外的特定签名吗?

1 个答案:

答案 0 :(得分:0)

如评论中所述,.NET对约束的支持是有限的,并且仅支持(i)无参数的构造函数和(ii)接口的实现。

F#遵循与普通泛型类型参数相同的重构,但是它也具有写为^T的静态解析类型参数,该参数可能具有更具表现力的约束。那些不是按照.NET约束进行编译的,而是在编译过程中被删除的,因此在这些约束上还有其他约束。

类似于使用静态成员约束的示例看起来像这样:

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)) }

约束必须位于内联成员(或内联函数)上,因此我要定义一个通用类型Foo<'T>,该类型具有静态成员Demo,可以用具有Create方法采用整数。例如:

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

我们现在可以使用Foo.Demo作为类型参数来调用Sample,然后返回Foo<Sample>,它是使用10作为初始化值创建的:

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