如何评估let中的依赖绑定?

时间:2015-07-24 03:44:11

标签: haskell

let中使用相互依赖的绑定是否安全?例如:

let x = 1
    y = x + 2
in y

它们是否可能并行评估?我的ghci表明它被正确评估,但总是这样吗?

2 个答案:

答案 0 :(得分:11)

Haskell是懒惰的评估。这意味着表达式仅根据需要进行评估。让我们从你的例子开始吧。

let x = 1
    y = x + 2
in y

系统查看y部分(表达式),并说"嘿。我知道y等于什么。它等于x + 2"但它只能评估x + 2是否有x的定义,因此它会做同样的事情并确定y1 + 2当然是3 }。现在这只是懒惰评估的一小部分力量。下一个例子更全面地展示了它。

let x = 0 : y
    y = 1 : x
in take 50 x

此表达式将正确评估,产生列表x上的前50个元素,它们将01交替显示。 xy这两个值都是相互依赖的无限列表,实际上在大多数语言中都会溢出堆栈。但是,评估规则允许系统仅查看所需的部分,在该示例中是前50个元素。

因此,为了回答有关评估顺序的问题,系统会评估它所看到的内容。如果该函数应该返回y,它将评估y,然后根据需要评估x。如果您在第一个示例中添加了x,则会评估x并单独留下y。例如,此代码不会出错。

let x = 1
    y = error "I'm an error message!"
in x

这是因为永远不需要y表单,因此甚至不会查看会导致程序崩溃的代码段。

答案 1 :(得分:2)

在Haskell中(无论您使用单个let,多个letcasewhere还是函数参数),在评估时都会评估表达式另一个表达取决于它的价值。

因此,在您的情况下,只要y的值是必需的(当然这取决于周围的程序),我们将评估y并将x评估为y评价的一部分。

另一种思考方式是:无论何时使用变量的值,最迟都会在该点进行评估。也就是说它可能先前已被评估过(如果以前需要它),或者现在可以进行评估,但是,只要您使用该值,它就永远不会被评估。因此,除了性能原因之外,无需担心何时评估变量。