创建彼此递归包含的抽象数据类型的实例
给定两个日期类型定义如下:
data Foo = Foo Bar String
data Bar = Bar Foo String
如何使 foo
和 bar
使得 foo
为 Foo bar "foo" 和
bar
是 Bar foo "bar"
?
当我们将类型更改为:
data Foo = Foo Bar (MVar String)
data Bar = Bar Foo (MVar String)
Given two date types defined as follows:
data Foo = Foo Bar String
data Bar = Bar Foo String
How can I make foo
and bar
such that foo
is Foo bar "foo"
and bar
is Bar foo "bar"
?
What about when we change the types to:
data Foo = Foo Bar (MVar String)
data Bar = Bar Foo (MVar String)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
只需使用
let
就足够了(Haskell 中的let
是letrec
,并且支持相互递归定义)。相互递归定义在堆中设置循环,如下所示:MVar< /code> 初始化并没有真正以任何有意义的方式改变事情。
Just using a
let
is enough (let
in Haskell isletrec
, and supports mutually recursive definitions). The mutually recursive definitions set up cycles in the heap, that look like this:The
MVar
initialization doesn't really change things in any meaningful way.Don 按要求回答了问题,但一个稍微有趣的问题是如何处理
现在这两个 MVar 不仅仅是递归的旁观者,他们是共犯。
这可以通过两种方式完成:
1.) 要么执行在命令式语言(如 C: 2.)中执行的操作
,要么使用 DoRec(以前称为 RecursiveDo)和
mfix
并在幕后将结:这相当于:
Don answered the question as asked, but a slightly more interesting question is how to deal with
Now the two MVars aren't mere bystanders to the recursion, they are accomplices.
This can be done two ways:
1.) Either by doing what you would do in an imperative language like C:
2.) or by using DoRec (formerly RecursiveDo) and
mfix
and behind the scenes tie the knot:This translates to something analogous to:
由于 Haskell 的懒惰,以下代码可以正常工作。
The following works fine thanks to Haskells lazyness.