I have been having difficulty understanding why the haskell expression let (x,y) = (y,1) in (x,y)
converges to (1,1)
as expected but fix (\(x,y)-> (y,1))
results in <<loop>>
being thrown. Can anyone explain this?
Haskell let expression converges while similar expression using fix does not
Asked Answered
By default, the outermost patterns used in let
bindings are lazy. However, patterns used in lambda bindings are strict, so the pattern match against the tuple forces too much too early. You can explicitly write a lazy pattern match by prefixing it with ~
, making the lambda pattern equivalent to the let
pattern:
ghci> fix (\(~(x, y)) -> (y, 1))
(1,1)
This defers the actual evaluation of the pattern match until one of bound variables is forced, instead of when the function is called, avoiding the loop.
For more information, see the Haskell wiki article on lazy patterns.
© 2022 - 2024 — McMap. All rights reserved.
let g (x,y) = (y,1) ; r = g r in r
. – Sejant