Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell let expression converges while similar expression using fix does not

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?

like image 281
Alexander Wittmond Avatar asked Jan 08 '18 02:01

Alexander Wittmond


1 Answers

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.

like image 83
Alexis King Avatar answered Sep 19 '22 21:09

Alexis King