Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell: Scope of variable when using lambda expression with bind functions

The following line works as expected, but I am a little concerned why:

getLine >>= \x-> getLine >>= \y-> return [x, y]

Consider the addition of parenthesis to scope the lambda expressions:

getLine >>= (\x-> getLine) >>= (\y-> return [x, y])

The second line is errorneous because x is not in scope when used in the return, and I am happy with this. What concerns me this that in the first line the scope of x appears to have 'leaked' out.

Is this 'leaking' considered bad practice? I am confused as to how it has remained in scope and not been lost immediately after the \x -> getLine expression.

like image 822
davetapley Avatar asked Nov 28 '22 12:11

davetapley


2 Answers

If you parenthesize your first line correctly according to haskell's precedence rules, you get:

getLine >>= (\x-> getLine >>= (\y-> return [x, y]))

This makes it obvious that the second lambda is inside the first, so there's no problem with it accessing the variables of the first lambda.

like image 94
sepp2k Avatar answered Dec 04 '22 11:12

sepp2k


You parentheses are simply set wrong. The correct parentheses are

getLine >>= (\x -> getLine >>= (\y -> return [x, y]))

And therefore, x is of course defined in the body.

Note that this feature is particularly useful since you can format code like this:

getLine >>= \x ->
getLine >>= \y ->
return [x, y]

which is almost

do
  x <- getLine
  y <- getLine
  return [x, y]

but without any special syntax.

like image 34
Dario Avatar answered Dec 04 '22 12:12

Dario