[英]Generic values in F# modules?
考虑一个通用容器,如:
type Foo<'t> =
{
Foo : 't
}
这个通用函数可以正常工作:
module Foo =
let inline emptyFoo () =
{
Foo = LanguagePrimitives.GenericZero
}
但是这个值不会:
module Foo =
let emptyFoo =
{
Foo = LanguagePrimitives.GenericZero
}
这是因为编译器推断emptyFoo
具有Foo<obj>
类型。
然而,标准库有像List.empty
这样的通用值,那么它是如何实现的呢?
你可以自己实现一个 List ,一个空的。 它看起来像这样。
type L<'a> =
| Null
| Cons of 'a * L<'a>
module L =
let empty = Null
let xs = Cons(1, Cons(2, L.empty))
let ys = Cons(1.0,Cons(2.0,L.empty))
那么,为什么L.empty
在这种情况下以通用方式工作? 因为值Null
没有附加任何特殊值。 你可以说,它与所有其他泛型兼容。
另一方面,在您的 Record 中,您始终必须产生一个值。 LanguagePrimitive.GenericZero
不是一些 Generic 值。 解析为一个特殊的零值是有帮助的,这个值是由你编写的其他代码决定的。
例如
let x = LanguagePrimitives.GenericZero
也是obj
let x = LanguagePrimitives.GenericZero + 1
将是int
。 和
let x = LanguagePrimitives.GenericZero + 1.0
会float
。 因此,在某些情况下,您可以将GenericZero
视为您需要的特殊类型的零占位符,但此时代码需要确定您想要哪种类型。
您可以更改您的类型,并选择提供一个真正的空。
type Foo<'t> = {
Foo: 't option
}
module Foo =
let empty = { Foo = None }
let x = Foo.empty // Foo<'a>
let y = { x with Foo = Some 1 } // Foo<int>
let z = { x with Foo = Some 1.0 } // Foo<float>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.