最近用 Haskell 处理字符串时不小心写出了这样的代码:
input = dropWhile myFilter input程序运行时陷入了死循环。排查了程序其他部分之后,我才发现问题原来出在这一行代码上。使用 Haskell 有一段时间了,居然是第一次犯这种基础错误,以至于完全没有意识到……
与许多程序语言不同,Haskell 中的 = 并不是赋值,而是定义,也就是说我们不能使用 x = x + 1 对 x 进行更新,而是遮蔽前一个 x 的定义。同时,由于 Haskell 的惰性求值策略,为了保持引用透明性,他不会先计算 x + 1 再遮蔽原来的定义,而是直接采用新的定义理解 x + 1 中的 x,因此产生了无限递归。
对于没有编程背景的人来说,应该是是 Haskell 的行为更加直观。我第一次接触 C 语言的时候,也为 x = x + 1; 这样的语句感到奇怪,不过现在思维已经完全改变了。