F# F中的类型推断#

F# F中的类型推断#,f#,type-inference,F#,Type Inference,在F#中,为什么我的add函数不添加两个float let add a b = a+b (add 3 4) //returns 7 (add 3.5 5.5) //error 另外,请解释类型推断在F#中是如何工作的 谢谢。您必须将其内联 let inline add a b = a+b 问题是+是一个内联运算符,因此如果函数add不是内联的,它将采用默认重载,即int 看看这个答案 当函数声明为内联时,类型推断将推断静态类型约束 val inline add : ^a ->

在F#中,为什么我的add函数不添加两个float

let add a b = a+b

(add 3 4) //returns 7
(add 3.5 5.5) //error
另外,请解释类型推断在F#中是如何工作的


谢谢。

您必须将其内联

let inline add a b = a+b
问题是
+
是一个内联运算符,因此如果函数add不是内联的,它将采用默认重载,即int

看看这个答案

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

val inline add :
   ^a ->  ^b ->  ^c
    when ( ^a or  ^b) : (static member ( + ) :  ^a *  ^b ->  ^c)
因此,现在a和b可以是实现带有该签名的静态成员(+)的任何类型。

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


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

let add (a:float) b = a + b //float -> float -> float
我的两分钱在这里

实际上如果你把执行顺序改成

let add a b = a+b

(add 3.5 5.5) //returns 9.0
(add 3 4) //error
您将看到F#确实增加了两个浮动。(这回答了您在F#中的问题,为什么我的add函数不添加两个浮点)

请注意,在这段代码中,F#推断函数add type为float->float->float

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

我认为在定义函数时,F#为函数提供int类型。但在内部,F#对函数的“真正”类型保持灵活。第一次调用函数时,编译器会看到您是如何使用它的,因此编译器会理解您对函数类型的“意图”。编译器会相应地调整类型

一旦编译器“认为”它得到了函数的“真正类型”,它就是这个类型。由于F#是静态类型的,因此不能使用其他类型的参数对函数进行第二次调用

话虽如此,我建议您尝试这些代码片段

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

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

你可能混淆C++中的类型推断和模板或者C语言中的泛型。谢谢提醒。我以后不会忘记这一点。称之为“技术限制”有点误导——这就是语言的设计方式!这有点像是说,由于技术限制,Haskell中的所有IO都需要在IO monad:-)中。