【问题标题】:Definition in Standard ML implementation file is externally visible (but not in the signature file)标准 ML 实现文件中的定义是外部可见的(但不在签名文件中)
【发布时间】:2019-01-16 11:44:27
【问题描述】:

我正在将 SML 起始代码从 Tiger book 转换为 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 中的等效代码是什么样的?很尴尬,因为函子IntMapTable的结果类型是Table,是文件的封闭模块。

【问题讨论】:

    标签: ocaml sml tiger


    【解决方案1】:

    使用 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,而不是两个模块Table_sigTable_fn。然后,OCaml 倾向于使用命名约定,例如调用签名 S 和函子 Make,因此在其他地方直观地将它们称为 Table.STable.Make

    2. 在某些情况下,您可以扁平化这个额外的包装结构。特别是:

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

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

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

    【讨论】:

      猜你喜欢
      • 2019-12-18
      • 2015-05-01
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 2012-04-22
      相关资源
      最近更新 更多