此代码无法编译:
let f = fun x y -> x <<< y // bit shift
let g = fun x y -> x <<< y
[<EntryPoint>]
let main _ =
printfn "%d" <| f 1 10
printfn "%d" <| f 1L 10 // error
printfn "%d" <| g 1L 10
0
(7,21): error FS0001: This expression was expected to have type
int
but here has type
int64
我想统一者在看到第一次出现时修复了与f
和g
相关联的类型参数。什么支配这个过程?我认为这与“价值限制”非常相似,但f
和g
已经完全扩展了!这是一个难题。
我肯定会想到在整数类型上使用ad-hoc多态来键入预定义运算符背后有一些黑魔法,但这只是我的推测。任何信息都赞赏。
答案 0 :(得分:2)
通用数字编程是使用静态成员约束完成的,这些约束无法在.NET类型系统中表示。它们仅存在于F#中,因此必须标记为inline
。
您的代码可以这样写:
let inline f x y = x <<< y // bit shift
let inline g z y = z <<< y
[<EntryPoint>]
let main _ =
printfn "%d" <| f 1 10
printfn "%d" <| f 1L 10 // works too
printfn "%d" <| g 1L 10
0
有关MSDN的更多信息:
Inline Functions
Statically Resolved Type Parameters
答案 1 :(得分:1)
我认为这是F#如何执行函数参数的自动泛化。在第一次出现时,它推断函数'f'可以具有类型('a - &gt;'a - &gt;'a)但第二个外观与此签名不匹配,因为它具有不同的签名('b - &gt;' a - &gt;'a)因为它将int64和int视为不同的类型。
内联函数有时可以像@Daniel提到的那样解决这个问题
可以在此处找到更多信息:http://msdn.microsoft.com/en-us/library/dd233183.aspx
有关静态成员约束的更多信息可以在Tomas Petricek的这篇文章中找到: http://tomasp.net/blog/fsharp-generic-numeric.aspx/