首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在标准ML中声明相互依赖的值和函数

在标准ML中声明相互依赖的值和函数
EN

Stack Overflow用户
提问于 2020-08-15 16:14:52
回答 2查看 202关注 0票数 2

在标准ML中,如何定义函数和值取决于彼此?

以下节目:

代码语言:javascript
复制
val cmds = [("help", cmd_help)];

fun cmd_help () = List.app (fn cmd => print (#1 cmd ^ "\n")) cmds;

cmd_help ();

不编译:

代码语言:javascript
复制
$ mlton example.sml
Error: example.sml 1.22-1.29.
  Undefined variable: cmd_help.

是否有可能对cmdscmd_help进行定义,使它们彼此了解,并将其作为顶级定义公开给程序的其他部分?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-16 11:01:43

有趣的问题是,最明显的方法是使cmds成为一个酉函数,然后在cmd_help中调用它,就像普通的一对递归函数一样。

代码语言:javascript
复制
fun cmds () = [("help", cmd_help)]
and cmd_help () = List.app (fn cmd => print ((#1 cmd) ^ "\n")) (cmds ());
cmd_help ();

人们可能会认为,您可以扭转这种情况,将cmds_help视为一个值。实际上,语法甚至看起来是解析的。

代码语言:javascript
复制
val a = ()
and b = fn () => ()

但是,当您将相互递归添加到工作中时,它实际上并不编译(我使用MLton和smlnj尝试了下面的内容)。手动声明类型,因为推断做得不是很好。

代码语言:javascript
复制
val cmds_v : (string * (unit -> unit)) list = [("help", cmd_help_v)]
and cmd_help_v : unit -> unit = fn () => List.app (fn (cmd: string * (unit -> unit)) => print ((#1 cmd) ^ "\n")) (cmds_v);

最后一个案例的结果是:

错误:未绑定变量或构造函数: cmds_v 错误:未绑定变量或构造函数: cmd_help_v

所以现在的问题是,如果我们看一下标准ML的定义(修订)脚注25中第42页的值绑定,为什么这个方法不能工作呢?

(25)当选项存在时,由于语法限制,我们有Dom、VE、∩、Dom、VE‘=∅。

因此,虽然函数的and允许相互递归,但是值的and允许确保值环境是不相交的。

唉,我不知道在不将值提升到函数的情况下如何做到这一点。

票数 3
EN

Stack Overflow用户

发布于 2021-01-08 22:36:56

我认为最好的解决方案是将函数封装在ref访问中,如下所示:

代码语言:javascript
复制
val cmd_help_ref : (unit -> unit) ref
    = ref (fn _ => raise Fail "cmd_help not bound");

fun cmd_help () = !cmd_help_ref ();

val cmds = [("help", cmd_help)];

cmd_help_ref := fn () => List.app (fn cmd => print (#1 cmd ^ "\n")) cmds;

cmd_help ();
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63428214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档