OCaml仿函数的语法糖

时间:2013-12-02 20:31:20

标签: syntax ocaml functor

为什么给出:

module type ENTRY = sig type t end       
module type LOG = functor (E : ENTRY) -> sig type t end 

这是LOG

的有效实现
module Log :LOG  = functor (LogEntry : ENTRY) -> 
  struct  type t = LogEntry.t list end

但这不是

module Log (LogEntry: ENTRY) :LOG  = struct
type t = LogEntry.t list end

Error: Signature mismatch:                                                                                                             
Modules do not match: sig type t = LogEntry.t list end is not included in LOG

如果我从Log的两个定义中删除了sig标签(:LOG),那么它们会返回相同的类型,因为它们只是语法糖[1]

[1] http://caml.inria.fr/pub/docs/oreilly-book/html/book-ora132.html

2 个答案:

答案 0 :(得分:3)

错误消息令人困惑,但第一个示例通过而第二个示例失败的原因实际上非常简单。比较:

type entry = int
type log = int -> string
let log : log = fun s -> string_of_int s

let log (s : entry) : log = string_of_int s

模块中的错误消息指出模块字段未包含在仿函数中,因为未应用的仿函数没有字段。

ETA:仿函数逻辑上不能有字段:函数/仿函数是一种“不同类型的动物”,而不是数据结构/模块。 - 这会使错误消息混乱,听起来我们被要求引入一个字段,尽管它已经存在于仿函数的 result 中。

答案 1 :(得分:2)

让我澄清 lukstafi 的回答。 LOG是仿函数的类型,在第一种情况下它与Log实现本身(实际上恰好是仿函数)相匹配,但在第二种情况下,它与结果匹配。仿函数应用程序(恰好是一个普通的模块),因此不匹配。

总而言之,这似乎是语法上的误解。仔细阅读section on module types in the manual