1

我正在将Tiger book中的 SML 入门代码转换为 OCaml。

让我感到困惑的是,在签名文件table.sig(如下)中,没有提及IntMapTable,但函子可以在另一个文件中访问而没有任何限制。

(* table.sig *)
signature TABLE =
sig
    ...
end

(* table.sml *)
functor IntMapTable (...) : TABLE =
struct
...
end

(* symbol.sml *)
...
structure Table = IntMapTable(...)
...

我的理解是,只有文件中的代码.sig可以访问外部模块,而不是文件中的代码.sml。不是这样吗?

此外,OCaml 中的等效代码可能是什么样的?这很尴尬,因为 functorIntMapTable的结果类型是Table,它是文件的封闭模块。

4

1 回答 1

4

使用 SML,文件及其名称都没有多大意义。它们只是将较大的来源分割成较小单元的一种方式。由多个文件组成的程序相当于这些文件以某种合适的顺序串联起来。

这在 OCaml 中有所不同,其中每个 .ml 文件本身都被视为从文件名派生的名称的结构,并且每个关联的 .mli 文件(如果存在)都被视为该结构上的不透明签名注释。

(Moscow ML,基于 OCaml 运行时的早期实现,是一个使用类似文件模型的 SML 实现。)

因此,当将 SML 文件移植到 OCaml 时,您有两个基本选择:

  1. 把它当成一个额外的结构来对待。例如,您table.sig可以成为table_sig.ml(不是.mli!)并且签名将被称为Table_sig.TABLE,而函子table.ml将成为table_fn.ml被称为Table_fn.IntMapTable

    有时您想稍微重新组织文件结构。例如,您可以选择只包含一个包含签名和函子的模块,而不是两个模块Table_sig和。然后,OCaml 倾向于使用命名约定,例如调用签名和函子,因此直观地将它们称为和别处。Table_fnTableSMakeTable.STable.Make

  2. 在某些情况下,您可以展平这个额外的包装器结构。尤其是:

    一个。如果文件包含一个 RHS 是struct表达式的单个结构声明,那么您可以将其主体放在以声明的结构命名的 .ml 文件中。

    湾。如果文件包含一个签名声明,其 RHS 是一个sig表达式,并且根据案例 (a) 仅使用一次来注释结构,那么您可以将其主体放在以相应结构命名的 .mli 文件中。

第二种往往是常见的情况。

于 2018-08-09T06:26:04.297 回答