我刚开始学习OCaml,而我正在玩一个字符串。
我正在浏览ocamlc
的剪辑是:
open Printf;;
type days =
| Monday
| Tuesday
| Wednesday
| Thursday
| Friday
| Saturday
| Sunday
let string_from_day day = match day with
| Monday -> "Monday"
| Tuesday -> "Tuesday"
| Wednesday -> "Wednesday"
| Thursday -> "Thursday"
| Friday -> "Friday"
| Saturday -> "Saturday"
| Sunday -> "Sunday"
let d = Monday;;
Printf.printf "The day is %s \n" (string_from_day d);;
运行得很好,它只打印出"The day is Monday"
。
但在Real World OCaml中,它表示我可以使用function
关键字定义我的函数。所以我重写了我的代码,看起来像:
open Printf;;
type days =
| Monday
| Tuesday
| Wednesday
| Thursday
| Friday
| Saturday
| Sunday
let string_from_day day = function
| Monday -> "Monday"
| Tuesday -> "Tuesday"
| Wednesday -> "Wednesday"
| Thursday -> "Thursday"
| Friday -> "Friday"
| Saturday -> "Saturday"
| Sunday -> "Sunday"
let d = Monday;;
Printf.printf "The day is %s \n" (string_from_day d);;
然而,这会产生以下错误:
Error: This expression has type days -> string
but an expression was expected of type string
我的问题是为什么?我的理解是string_from_day
函数应该在两个版本中评估为字符串。
当我使用match
关键字将函数输入顶层时,我得到了
val string_from_day : days -> bytes = <fun>
当我使用function
关键字将函数输入顶级时,我得到了
val string_from_day : 'a -> days -> bytes = <fun>
我发现顶级结果对于两者都不同但是curry函数以bytes
结束,并不重要吗? Real World OCaml 书中说这些是等价的,但似乎并非如此。任何解释或指向更多信息的指针将不胜感激。
答案 0 :(得分:4)
使用关键字function
时,不得在函数声明中写入参数名称,因为不再需要它。这就是你想写的:
let string_of_day = function
| Monday -> ...
仔细检查RWO中给出的例子:
# let some_or_zero = function
| Some x -> x
| None -> 0
;;
val some_or_zero : int option -> int = <fun>
# List.map ~f:some_or_zero [Some 3; None; Some 4];;
- : int list = [3; 0; 4]
函数的声明没有提到参数。实际上,它不是必需的,因为它立即被赋予模式匹配。
请注意
let f = function ...
严格等同于
let f x = match x with ...