let
is a practical way to handle this. But perhaps itβs worth unpacking what really happens here. The do
statement does not cause problems with scoping.
remember, that
main = do s <- getLine putStr magic where magic = doMagic s
equivalent to this:
main = getline >>= \s -> putStr magic where magic = doMagic s
If we introduce some brackets, this is:
main = getline >>= (\s -> putStr magic) where magic = doMagic s
Here comes the region s
: this is an argument for the lambda expression, and it exists only inside this lambda expression. Try using it in the where
clause outside of this lambda, and you get an "out of scope" error.
let
works because let
and where
handled differently. With parentheses for clarity:
foo = (\x -> let y = x in y) -- Works fine foo'' = (\x -> y) where y = x -- y is not in scope
This is what causes the problem; this does not apply to IO or do
statements.
source share