Haskell 让表达式收敛,而使用 fix 的类似表达式不收敛

Haskell let expression converges while similar expression using fix does not

我一直难以理解为什么 haskell 表达式 let (x,y) = (y,1) in (x,y) 按预期收敛到 (1,1)fix (\(x,y)-> (y,1)) 导致 <<loop>> 被抛出。谁能解释一下?

默认情况下,let 绑定中使用的最外层模式是惰性模式。然而,lambda 绑定中使用的模式是严格的,因此模式与元组的匹配太早了。您可以通过在前缀 ~ 前显式编写惰性模式匹配,使 lambda 模式等同于 let 模式:

ghci> fix (\(~(x, y)) -> (y, 1))
(1,1)

这推迟了模式匹配的实际评估,直到强制绑定变量之一,而不是在调用函数时,避免了循环。

有关详细信息,请参阅 Haskell wiki article on lazy patterns