Haskell中使用let表达式收敛,而使用fix的类似表达式却不收敛。

17

我一直很难理解为什么Haskell表达式let (x,y) = (y,1) in (x,y)会如预期地收敛到(1,1),但fix (\(x,y)-> (y,1))会抛出<<loop>>。 有人可以解释一下吗?


修复表达式等同于 let g (x,y) = (y,1) ; r = g r in r - Will Ness
1个回答

21

默认情况下,在 let 绑定中使用的最外层模式是惰性的。然而,在 lambda 绑定中使用的模式是严格的,因此对元组进行模式匹配会过早地强制执行太多操作。您可以在模式前加上 ~ 来显式编写惰性模式匹配,使 lambda 模式等效于 let 模式:

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

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

更多信息,请参见Haskell闲置模式的维基文章


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接