[英]Generic values in F# modules?
Consider a generic container like:考虑一个通用容器,如:
type Foo<'t> =
{
Foo : 't
}
This generic function works OK:这个通用函数可以正常工作:
module Foo =
let inline emptyFoo () =
{
Foo = LanguagePrimitives.GenericZero
}
But this value does not:但是这个值不会:
module Foo =
let emptyFoo =
{
Foo = LanguagePrimitives.GenericZero
}
This is because the compiler infers emptyFoo
to have type Foo<obj>
.这是因为编译器推断
emptyFoo
具有Foo<obj>
类型。
However, the standard library has generic values like List.empty
, so how is that achieved there?然而,标准库有像
List.empty
这样的通用值,那么它是如何实现的呢?
You could implement a List by yourself, with an empty.你可以自己实现一个 List ,一个空的。 It looks like this.
它看起来像这样。
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))
So, why does L.empty
in this case works in a generic way?那么,为什么
L.empty
在这种情况下以通用方式工作? Because the value Null
has no special value attached to it.因为值
Null
没有附加任何特殊值。 You could say, it is compatible with every other generic.你可以说,它与所有其他泛型兼容。
In your Record on the other hand, you always must produce a value.另一方面,在您的 Record 中,您始终必须产生一个值。
LanguagePrimitive.GenericZero
is not some Generic value. LanguagePrimitive.GenericZero
不是一些 Generic 值。 It help so to resolve to a special zero value, and this value is determined by the other code you write.解析为一个特殊的零值是有帮助的,这个值是由你编写的其他代码决定的。
For example例如
let x = LanguagePrimitives.GenericZero
is also obj
也是
obj
let x = LanguagePrimitives.GenericZero + 1
will be int
.将是
int
。 And和
let x = LanguagePrimitives.GenericZero + 1.0
will be float
.会
float
。 So in some case you can think of GenericZero
just as a placeholder for zero for the special type you need, but the code needs to determine at this point, which type you want.因此,在某些情况下,您可以将
GenericZero
视为您需要的特殊类型的零占位符,但此时代码需要确定您想要哪种类型。
You could change your type, with an option to provide a real empty.您可以更改您的类型,并选择提供一个真正的空。
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.