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

时间:2018-01-08 02:55:26

标签: haskell mutual-recursion

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

1 个答案:

答案 0 :(得分:21)

默认情况下,let绑定中使用的最外层模式是惰性的。但是,lambda绑定中使用的模式是严格的,因此与元组匹配的模式过早地过于强大。您可以通过在~前面添加前缀来显式编写延迟模式匹配,从而使lambda模式等同于let模式:

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

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

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