3

sml可以通过and关键字定义相互依赖的数据类型。现在我有两个相互引用的结构,我看到的错误似乎是因为它是相互递归的,但我看不到一种方法可以and以这样的方式添加,这可能会起作用。

例子:

structure Machine = struct 
  structure F = Frame
  ...
end

structure Frame = struct
  ...
  reference to Machine.wordsize
end

这可以工作还是设计不兼容sml?我正在从那里移植代码Ocaml,显然这在那里有效。

4

2 回答 2

9

在标准 ML 中,两个结构不能直接相互引用。事实上,即使是一个结构也不能直接引用它自己;在类似structure S = struct ... end的情况下,结构标识符中的任何出现S...必须引用一些先前定义的结构S,而不是当前正在定义的结构。(这是因为定义第 32 页上的推理规则 57 和 61 ,它们定义了结构声明和结构绑定的详细说明。为了使这种详细说明是递归的,生成的结构环境SE必须出现在左侧-这些规则之一中假设的手边。)语法确实允许使用and(在规则中)组合结构绑定strbind定义的第 13 页),但它的效果与你想要的相反:在类似的东西中structure S = struct ... end and T = struct ... end,你甚至不能T引用S(因为两个绑定都是在相同的基础上详细阐述的,这意味着绑定的结果S是在 ) 的绑定中不可用T

但是,有可能实现您想要的;你只需要稍微倾斜一点。例如,一种方法是将两个声明放在一个local声明中,所有重要位都声明在顶部:

local
  ... (* everything needed for both Frame and Machine *) ...
in
  structure Frame = struct ... end
  structure Machine = struct ... end
end

另一种方法是稍微零碎地声明结构,并进行连续的改进:

structure Machine = struct ... wordsize ... end
structure Frame = struct ... M.wordsize ... end
structure Machine = struct open Machine ... end

(这里Machine最后一个声明中提到的是第一个声明中绑定的那个。)这种连续的细化有时用于在创建朋友后“密封”一个结构:

structure Foo = struct ... end
... (* code that has full access to the guts of Foo *) ...
structure Foo = Foo : sig ... end
... (* code that only sees what's exposed in the signature *) ...
于 2013-06-09T19:47:49.257 回答
2

似乎这是不可能的。我在这里找到了答案。

1.2.0节第二个问题的答案,Q: [Allyn Dimock] Recursive modules

许多人要求定义相互递归结构的方法(例如,命令和表达式的相互递归抽象语法,每个都在其自己的模块中)。这是可以做到的,尽管这组相互递归的模块几乎肯定必须作为单个编译单元进行编译,因此它们不会是真正的“独立”模块。然而,具有涉及函子应用程序的递归定义似乎要困难得多,并且相互递归的函子将更加令人难以置信。

于 2013-06-09T19:09:02.697 回答