OCaml匹配和功能差异的说明

时间:2017-03-24 17:02:15

标签: function pattern-matching ocaml

我刚开始学习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 书中说这些是等价的,但似乎并非如此。任何解释或指向更多信息的指针将不胜感激。

1 个答案:

答案 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 ...