【问题标题】:type inference in F#F# 中的类型推断
【发布时间】:2013-11-02 05:14:14
【问题描述】:

在 F# 中,为什么我的 add 函数没有添加两个浮点数

let add a b = a+b

(add 3 4) //returns 7
(add 3.5 5.5) //error

还请解释类型推断在 F# 中的工作原理。

谢谢。

【问题讨论】:

  • 您可能会混淆 C++ 中的类型推断和模板或 C# 中的泛型。
  • 谢谢提醒。以后不会忘记的。

标签: f# type-inference


【解决方案1】:

你必须让它内联。

let inline add a b = a+b

问题是+ 是一个内联运算符,所以如果你的函数 add 不是内联的,它将采用默认的重载,即 int。

看看这个答案Use of `inline` in F#

当函数被声明为内联时,类型推断将推断静态类型约束。

val inline add :
   ^a ->  ^b ->  ^c
    when ( ^a or  ^b) : (static member ( + ) :  ^a *  ^b ->  ^c)

所以现在 a 和 b 可以是使用该签名实现静态成员 (+) 的任何类型。

【讨论】:

    【解决方案2】:

    如果您只想让函数使用浮点数,请使用类型注释。

    let add (a:float) b = a + b //float -> float -> float
    

    【讨论】:

      【解决方案3】:

      在 F# 中,由于技术限制,当您处理数字时,类型推断系统只会放置一个类型 int。 在 Haskell 中,add :: Num a => a -> a -> a 工作是因为类型类,这与 .NET 类不同。类型类不适合 F#。

      http://en.wikibooks.org/wiki/F_Sharp_Programming/Basic_Concepts#Type_Inferencehttp://en.wikibooks.org/wiki/F_Sharp_Programming/Values_and_Functions

      【讨论】:

      • 称“技术限制”有点误导 - 这就是语言的设计方式!这有点像说,由于技术限制,Haskell 中的所有 IO 都需要在 IO monad 中:-)。
      【解决方案4】:

      我的两分钱在这里。

      其实如果你把执行的顺序改成,

      let add a b = a+b
      
      (add 3.5 5.5) //returns 9.0
      (add 3 4) //error
      

      您会看到 F# 确实添加了两个浮点数。 (这回答了你在 F# 中的问题,为什么我的 add 函数不添加两个浮点数)

      请注意,在这个 sn-p 中,F# 将函数添加类型推断为 float -> float -> float。

      为什么即使你以完全相同的方式定义函数,F# 在这两种情况下也会以不同的方式推断函数类型?

      我认为当你定义函数时,F# 将类型 int 赋予函数。但在内部,F# 对函数的“真实”类型保持灵活。第一次/第一次调用函数时,编译器会看到你如何使用它,因此编译器会理解你对函数类型的“意图”。并且编译器会相应地调整类型。

      一旦编译器“认为”它得到函数的“真实类型”,它就是它的样子。由于 F# 是静态类型的,因此您无法使用不同类型的参数再次调用该函数。

      话虽如此,我建议你试试这些 sn-p。

      let add a b = a + b
      
      add "str" "ing"
      

      它应该可以工作。

      let add a b = a + b
      
      add 5. 6.
      add "str" "ing" // error, check the type
      

      如果我错了,请纠正我。希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-25
        • 2013-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-29
        • 2012-07-17
        • 1970-01-01
        相关资源
        最近更新 更多