“打结”解释

在阅读Haskell相关的东西时,我有时会遇到“绑结”的expression,我想我明白它做了什么 ,但不知道如何

那么,对这个概念的解释有没有什么好的,基本的和简单的?

捆绑结是解决循环数据结构问题的方法。 在命令式语言中,首先创build一个非圆形结构,然后返回并修正指针以添加圆形。

假设您想要一个包含元素“0”和“1”的双元素圆形列表。 这似乎是不可能的,因为如果你创build“1”节点,然后创build“0”节点指向它,你不能然后回去修复“1”节点指向“0”节点。 所以你有一个鸡与蛋的情况下,两个节点都需要存在之前,可以创build。

这里是你如何在Haskell中完成的。 考虑以下值:

alternates = x where x = 0 : y y = 1 : x 

在一个非懒惰的语言,这将是一个无限循环,因为未终结的recursion。 但是在Haskell懒惰的评估中做了正确的事情:它产生了一个两元素的循环列表。

要看看它在实践中是如何工作的,请考虑运行时发生的情况。 懒惰评估的通常“thunk”实现代表一个未评估的expression式,作为包含函数指针加上要传递给函数的参数的数据结构。 当评估时,thunk被实际值replace,以便将来的引用不必再次调用该函数。

当列表中的第一个元素被评估为一个值(0,&y)时,“&y”位是一个指向“y”值的指针。 由于'y'没有被评估,这目前是一个thunk。 当你拿到列表的第二个元素时,计算机会跟随从x到这个thunk的链接并对其进行评估。 它的计算结果是(1,&x),换句话说,是一个指向原始“x”值的指针。 所以你现在有一个循环的名单坐在记忆中。 程序员不需要修复后台指针,因为懒惰的评估机制为你做了。

这不是你所要求的,它与Haskell没有直接关系,但是Bruce McAdam的文章“About Wraps It Up”深入讨论了这个话题。 Bruce的基本思路是使用一个名为WRAP的显式连接运算符,而不是在Haskell,OCaml和其他一些语言中自动完成的式连接。 这篇论文有很多有趣的例子 ,如果你对打结感兴趣,我想你会对这个过程有更好的感觉。