let log x = print_int x; log ;;
log 111 222;;
我期待
log
打印 111
并返回自身,然后在第二次调用时打印 222
,但它没有按预期工作,而是收到一条错误消息。为什么?如何让它按预期工作?
我也尝试了
rec
但没有成功。
File "./hello.ml", line 3, characters 8-11:
3 | log 111 222;;
^^^
Error: This expression has type int but an expression was expected of type
float
如果你尝试这个:
let log x = print_int x; log
您返回的是已经存在的
log
,其类型为 float -> float
,因此类型不匹配。
如果你尝试:
let rec log x = print_int x; log
类型系统变得混乱。你的
log
正在接受一个 int
并返回...一个接受 int
并返回一个接受 int
并返回... 的函数
除非启用递归类型,否则这种递归性不起作用。
% ocaml -rectypes
OCaml version 4.14.0
Enter #help;; for help.
# let rec log x = print_int x; log;;
val log : int -> 'a as 'a = <fun>
# log 222 111;;
222111- : int -> 'a as 'a = <fun>
关联性注意事项:与
as
在模式匹配中的作用类似,这里它抓取左侧的所有内容,因此 int -> 'a as 'a
读作 (int -> 'a) as 'a
而不是 int -> ('a as 'a)
。
回答OP的下一个问题详细说明为什么默认情况下不启用此选项。
除非您将
log
声明为递归函数,否则它的返回值将是其他函数,即 log
的先前定义。事实上,log
是一个接受浮点值并返回浮点值的函数。
如果你确实将
log
声明为递归,你将会遇到更多问题。特别是,您的函数将具有递归类型。您可以使用 -rectypes
标志使其发挥作用。
(我会更全面地解释,但是@Chris 在我写这篇文章时给出了很好的解释。)