[英]Types and functions
Consider the following: 考虑以下:
type T () =
member x.y = 4
let a =
let fn () (k: T) = ()
fn ()
let b =
let fn () (k: System.IO.Directory) = ()
fn ()
a
fails while b
is ok. a
而未能b
是确定的。 The error message is: 错误消息是:
The value 'a' has been inferred to have generic type val a : ('_a -> unit) when '_a :> T Either make the arguments to 'a' explicit or, if you do not intend for it to be generic, add a type annotation
值'a'被推断为具有泛型类型val a:('_a - > unit)当'_a:> T要么使参数'a'显式,要么如果你不打算使它是通用的,添加类型注释
Why and how to fix that? 为什么以及如何解决这个问题?
The error message itself tells you exactly what you need to do - add a type annotation: 错误消息本身告诉您确切需要做什么 - 添加类型注释:
let a : T -> unit =
let fn () (k: T) = ()
fn ()
The reason that you see the error in the first place is that the compiler tries to generalize the definition of a
(see this part of the spec), which results in the odd signature that you see in the error message. 您看到的错误摆在首位的原因是编译器试图概括的定义
a
(见这部分的规范),这将导致你错误消息见奇签名。
The reason that you don't need to do this for b
is that System.IO.Directory
is sealed, so there is no need to generalize. 您不需要为
b
执行此操作的原因是System.IO.Directory
已被密封,因此无需进行概括。
You are facing a value restriction, because a
looks like a constant but it returns a function. 您正面临一个值限制,因为
a
看起来像一个常量,但它返回一个函数。 Have a look at this question: 看看这个问题:
Understanding F# Value Restriction Errors 了解F#值限制错误
One easy way to solve it is adding a variable to the definition of a
. 一个简单的方法来解决它是加入一个变量来定义
a
。
let a x =
let fn () (k: T) = ()
fn () x
I don't know why with some types it works, which is the case of b
我不知道为什么它的某些类型有效,这就是
b
的情况
If T where a record instead of a class, it would work. 如果T所在的记录而不是类,那就行了。 But for some reason, you have to spell it out for the compiler if T is a class,
但出于某种原因,如果T是一个类,你必须拼写出编译器,
type T () =
member x.y = 4
let a<'U when 'U :> T> =
let fn () (k: 'U) = ()
fn ()
let test0 = a<T> (T()) // You can be explicit about T,
let test1 = a (T()) // but you don't have to be.
edit: So I played a bit more with this, and weirdly, the compiler seems to be content with just any type restriction: 编辑:所以我用这个玩了一下,奇怪的是,编译器似乎满足于任何类型的限制:
type T () =
member x.y = 4
type S () =
member x.z = 4.5
let a<'U when 'U :> S> =
let fn () (k: T) = ()
fn ()
let test = a (T()) // Is OK
let test = a<T> (T()) // Error: The type 'T' is not compatible with the type 'S'
The type S has nothing to do with anything in the code above, still the compiler is happy to just have a restriction of any kind. 类型S与上面的代码中的任何内容无关,编译器仍然乐于接受任何类型的限制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.