OCaml 函数子类型的语法糖

3
为什么会出现以下情况:
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

使用OCaml编译器版本4.01.0 - Heidi
2个回答

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

在模块出现错误的情况下,错误信息显示一个模块字段没有包含在函数对象中,因为未应用的函数对象没有字段。
附注:函数对象逻辑上不能有字段:函数/函数对象与数据结构/模块是“不同类型的东西”。这使得错误信息很困惑,听起来好像我们被要求引入一个已经存在于函数对象结果中的字段。

2
让我澄清一下的回答。 LOG是函子的类型,在第一种情况下,它与Log实现本身匹配(它确实是一个函子),但在第二种情况下,它与函子应用的结果匹配(它确实是一个普通模块),因此不匹配。
总的来说,这似乎是语法上的误解。请仔细阅读手册中关于模块类型的部分内容

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接