Scale specific variables

I found that when IO in Haskell, variables that are assigned using the <- operator <- available only to the operators immediately after them, and not in the where clauses.

For instance:

 main :: IO() main = do s <- getLine putStr magic where magic = doMagic s 

This will not work as s not in scope. I did some research to confirm this, and found this article :

Unlike the let expression, where variables are covered by all definitions, variables defined by <- are only in scope in the following statements.

So, how can I make s available for use in the where clause?

+4
source share
3 answers

In addition to the general let form, there is a special let form for use with do syntax, which you can use instead:

 main :: IO() main = do s <- getLine let magic = doMagic s putStr magic 

magic is available in all the following lines of the block.

+6
source

Well, magic is a function. So you can do something like:

 magic m = doMagic m 

Or:

 magic = \m-> doMagic m 

And call it that:

 putStrLn $ magic s 

Of course, as you already explored, the reasonable thing when you can reuse computed magic is to use the let ... in expression and nest the calls:

 let magic_str = magic s in putStrLn magic_str 
+1
source

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.

+1
source

All Articles