F#: arithmetic operator and loss of polymorphism (value restriction?)

与世无争的帅哥 提交于 2019-12-11 20:42:23

问题


This code doesn't compile:

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

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.

  • http://en.wikipedia.org/wiki/Value_restriction

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.


回答1:


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.

Your code could be written this way:

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




回答2:


I think it is how F# performs automatic generalization of function parameters. On first appearance it infers that the function 'f' could have type ('a -> 'a -> 'a) but the second appearance is not match this signature because it has a different signature ('b -> 'a -> 'a) because it consider int64 and int as different types.

Inlining functions could sometimes solve this problem as @Daniel mentioned

Slightly more info could be found here: http://msdn.microsoft.com/en-us/library/dd233183.aspx

Some more info on static member constraints could be found in this post by Tomas Petricek: http://tomasp.net/blog/fsharp-generic-numeric.aspx/



来源:https://stackoverflow.com/questions/26632912/f-arithmetic-operator-and-loss-of-polymorphism-value-restriction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!