F# F中的类型推断#
在F#中,为什么我的add函数不添加两个floatF# 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 ->
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:-)中。