以下 Haskell 代码不会终止,有人可以解释一下原因吗?谢谢。
f = let x = 10 in let x = x * x in x
我认为解释器首先绑定(bind) x : 10, 然后将 x * x 评估为 100 并绑定(bind) x : 100, 环境变为 x : 100, 那么整个表达式的计算结果为 100
但是,此代码不会终止。
最佳答案
当评估 let foo = bar in baz
形式的 let 语句时,foo
在评估 时已经绑定(bind)到
- 即定义是递归的,如果有同名的外部绑定(bind),它会被忽略,因为它不再在范围内。bar
>bar
在评论中,您询问了为什么您没有收到关于 x
查找失败的错误。原因是 x
的查找没有失败。 Haskell 知道 x
等于 x * x
,所以这就是查找产生的结果。
所以当 x
被求值时,它被它的定义 x * x
替换。为了评估它然后用它的定义替换第一个 x
,产生 x * x * x
,然后是 x * x * x * x
以此类推。
您可能想知道为什么允许值以这种方式递归,所以这里有一个非常有用的示例,它不仅会导致无限循环:let xs = 42 : xs in take 2 xs
产生结果 [42, 42]
。这里 xs
被扩展为 42 : xs
然后 42 : 42 : xs
然后它停止因为 take 2
只需要前两个元素,这就是它停止的地方。
当然,当 rhs 是一个函数时,很明显,递归定义很有用: let fac =\n -> if n = 0 then 1 else n * fac (n-1 )
- 这里你显然希望 fac
引用自身,而不是以前的 fac
定义。
关于haskell - 绑定(bind)变量时Haskell中的无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28553559/