我一直很难理解为什么Haskell表达式let (x,y) = (y,1) in (x,y)
会如预期地收敛到(1,1)
,但fix (\(x,y)-> (y,1))
会抛出<<loop>>
。 有人可以解释一下吗?
我一直很难理解为什么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闲置模式的维基文章。
let g (x,y) = (y,1) ; r = g r in r
。 - Will Ness