F#:算术运算符和多态性损失(值限制?) [英] F#: arithmetic operator and loss of polymorphism (value restriction?)

查看:183
本文介绍了F#:算术运算符和多态性损失(值限制?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码无法编译:

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
    • 我猜统一器在看到它们第一次出现时就修复了与fg关联的类型参数.什么决定了这个过程?我认为这与值限制"非常相似,但是fg已经被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
      

      有关MSDN的更多信息:
      内联函数
      静态解析的类型参数

      More info on MSDN:
      Inline Functions
      Statically Resolved Type Parameters

      这篇关于F#:算术运算符和多态性损失(值限制?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆