F#:算术运算符和多态性损失(值限制?) [英] F#: arithmetic operator and loss of polymorphism (value restriction?)
问题描述
此代码无法编译:
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
- http://ideone.com/qktsOb
- http://ideone.com/qktsOb
我猜统一器在看到它们第一次出现时就修复了与f
和g
关联的类型参数.什么决定了这个过程?我认为这与值限制"非常相似,但是f
和g
已经被eta扩展了!这是一个难题.
I guess the unifier fixed the type parameters associated with f
and g
upon seeing their first occurrences. What governs this process? I think this is very similar to "value restriction" but f
and g
are already eta-expanded! This is a hard problem.
我当然可以想象,在预定义的运算符后面加上整数类型具有特殊的多态性,这会带来一些不可思议的魔力,但这只是我的猜测.任何信息表示赞赏.
I would surely imagine there's some black magic behind typing predefined operators with ad-hoc polymorphism over integral types, but that's just my speculation. Any information appreciated.
推荐答案
通用数字编程是使用静态成员约束完成的,该成员约束无法在.NET类型系统中表示.它们仅存在于F#中,因此必须标记为inline
.
Generic numeric programming is done using static member constraints, which can't be represented in the .NET type system. They exist only in F# and therefore must be marked 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
More info on MSDN:
Inline Functions
Statically Resolved Type Parameters
这篇关于F#:算术运算符和多态性损失(值限制?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!