我故意将x添加到此函数的末尾
let myMax x y =
if x > y then x else y
x
我原以为x和y参数仍然是'一种类型,但我得到了这个签名:
myMax : x:unit -> y:unit -> unit
为什么推断这些参数具有单位类型?
编辑: 谢谢@gilles的答案。考虑这两个功能:
let foo x y =
0 // warning
x
val foo : x:'a -> y:'b -> 'a
let foo2 x y =
if x > y then x else y // no warning
x
val foo2 : x:unit -> y:unit -> unit
是什么让两个签名不同? 似乎在第二个函数中,编译器将比较的结果 - x或y-作为单位
解释答案 0 :(得分:7)
让我们写一个更简单的例子:
> fun x -> x; 0;;
val it : unit -> int = <fun:clo@5>
在复合表达式中,分号/换行符之前的表达式必须具有单位类型。如果要使用具有“实际”值的表达式(即除单位以外的任何类型),则需要显式忽略它,或将其绑定到无变量模式。如果表达式的类型不能与unit
统一,编译器会提醒您:
> fun x -> 0; x;;
fun x -> 0; x;;
---------^
stdin(7,10): warning FS0020: This expression should have type 'unit', but has type 'int'.
Use 'ignore' to discard the result of the expression,
or 'let' to bind the result to a name.
val it : x:'a -> 'a = <fun:clo@7-1>
有可能在;
之前有一个允许任何类型的输入规则 - 毕竟忽略了这个值,所以它的类型无关紧要 - 但这会很容易意外地丢弃一个返回重要的价值。因此,如果您想忽略该值,请明确地这样做:
let myMax x y =
ignore (if x > y then x else y)
x
或
let myMax x y =
let _ = if x > y then x else y
x