如何强制类型签名
How to enforce type signature
在下面的代码中,queue_it
以一种意想不到的方式改变了类型签名。我该如何解决?
module foo =
type MBase() =
member __.id = 42
type User() = inherit MBase()
type User2() = inherit MBase()
let queue_it f = fun x -> f x
let _find(x:int) = (Unchecked.defaultof<#MBase>)
let find0 = fun x -> _find x // int -> #MBase
let findq0 = queue_it _find // int -> MBase ??
let u1 : User = find0 42
let u2 : User2 = find0 42
let u3 : User = findq0 42
let u4 : User2 = findq0 42 // error: Expected User2 but given User
如何解决是比较容易的部分,使 findq0
成为 通用函数:
let findq0 x = queue_it _find x // int -> 'a
与你所拥有的不同之处在于你的版本
let findq0 = queue_it _find // int -> User
findq0
是一个 通用值 ,这是 .Net 的一个问题,通常会导致这样的错误消息
Value restriction. The value 'findq0' has been inferred to have
generic type
val findq0 : (int -> '_a) when '_a :> Answer.foo.MBase Either make the arguments to 'findq0' explicit or, if you do not intend for
it to be generic, add a type annotation.
如果您注释掉代码的最后两行,您可以看到该消息。 F# 尝试根据您对 findq0
的首次使用猜测一个非泛型值来避免出现该消息,即:
let u3 : User = findq0 42
这一行告诉 F# findq0
应该 return 类型 User
的值,因此它确定它应该是 int -> User
类型。下一行与它相矛盾,因此您会收到一条错误消息:
This expression was expected to have type
'User2' but here has type
'User'
在下面的代码中,queue_it
以一种意想不到的方式改变了类型签名。我该如何解决?
module foo =
type MBase() =
member __.id = 42
type User() = inherit MBase()
type User2() = inherit MBase()
let queue_it f = fun x -> f x
let _find(x:int) = (Unchecked.defaultof<#MBase>)
let find0 = fun x -> _find x // int -> #MBase
let findq0 = queue_it _find // int -> MBase ??
let u1 : User = find0 42
let u2 : User2 = find0 42
let u3 : User = findq0 42
let u4 : User2 = findq0 42 // error: Expected User2 but given User
如何解决是比较容易的部分,使 findq0
成为 通用函数:
let findq0 x = queue_it _find x // int -> 'a
与你所拥有的不同之处在于你的版本
let findq0 = queue_it _find // int -> User
findq0
是一个 通用值 ,这是 .Net 的一个问题,通常会导致这样的错误消息
Value restriction. The value 'findq0' has been inferred to have generic type val findq0 : (int -> '_a) when '_a :> Answer.foo.MBase Either make the arguments to 'findq0' explicit or, if you do not intend for it to be generic, add a type annotation.
如果您注释掉代码的最后两行,您可以看到该消息。 F# 尝试根据您对 findq0
的首次使用猜测一个非泛型值来避免出现该消息,即:
let u3 : User = findq0 42
这一行告诉 F# findq0
应该 return 类型 User
的值,因此它确定它应该是 int -> User
类型。下一行与它相矛盾,因此您会收到一条错误消息:
This expression was expected to have type 'User2' but here has type 'User'