Haskell: 为什么把一个变量的尾部重新赋值给自己的变量会出问题?

Haskell: Why is it a problem to re-assign the tail of a variable to its own variable?

假设您有一个包含以下列表的变量:

Prelude> arr = [1,2,3,4,5]

而你,

Prelude> arr
[1,2,3,4,5]
Prelude> arr = tail arr
Prelude> arr

为什么编译器现在死机了?我试图在递归中实现此代码语句,但这种现象使我的递归无法正常工作——它一直返回一个空列表错误。

在Haskell中,变量总是在它自己定义的范围内。你可能想要的是这个

Prelude> arr1 = [1,2,3,4,5]
Prelude> arr1
[1,2,3,4,5]
Prelude> arr2 = tail arr1
Prelude> arr2
[2, 3, 4, 5]

但是当你写 arr = tail arr 时,REPL 忘记了之前 arr 的定义并定义了一个等于 它自己的 尾巴的新定义。那你做

Prelude> arr

Haskell 出现并将其计算为 tail arrtail evaluates its argument to WHNF, so to identify tail arr, we need to know the shape of arr, which is, of course, tail arr. So to know arr, we need to know arr. Hence, arr is bottom,一个非终止值。之前的定义无关紧要。

如果您曾尝试在 Haskell 源文件中执行此操作(与命令行交互环境相反),您会遇到编译器错误,因为在相同的范围。这只是 REPL 的一项功能,允许您出于测试目的这样做。