可以通过sml
关键字在and
中定义相互依赖的数据类型。现在我有两个相互引用的结构,看起来我看到的错误是因为它是相互递归的,但我没有看到以这种方式添加and
的方法。
示例:
structure Machine = struct
structure F = Frame
...
end
structure Frame = struct
...
reference to Machine.wordsize
end
这可以使用还是设计与sml
不兼容?我正在从Ocaml
移植代码,显然这可以在那里工作。
答案 0 :(得分:9)
在标准ML中,两个结构不能直接相互引用。事实上,即使是一个结构也不能直接引用自身;在structure S = struct ... end
之类的内容中,S
中任何结构标识符...
的出现都必须引用一些先前定义的结构S
,而不是当前正在进行的结构and
。定义。 (这是因为 Definition 的第32页上的推理规则57和61,它定义了如何详细说明结构声明和结构绑定。为了使这个详细说明是递归的,得到的结构环境 SE 必须出现在这些规则之一的假设的左侧。)语法允许使用structure S = struct ... end and T = struct ... end
组合结构绑定(在 strbind的规则中) 定义的第13页上的,但其效果与您想要的相反:在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 *) ...
是第一个声明中绑定的那个。)这种连续的细化有时用于在创建朋友后“封印”结构:
{{1}}
答案 1 :(得分:2)
似乎不可能。我找到了答案here。
第1.2.0节中第二个问题的回答,Q: [Allyn Dimock] Recursive modules
许多人要求一种定义相互递归的方法 结构(例如命令和命令的相互递归抽象语法) 表达式,每个都在自己的模块中)。这可以做到,尽管如此 一组相互递归的模块几乎肯定是必须的 编译为单个编译单元,因此它们不会是真正的 “独立”模块。但是,具有涉及的递归定义 仿函数应用程序看起来要困难得多,相互之间 递归仿函数会更令人难以置信。