Why is it not lazy

I'm still starting to learn Haskell. I know that this code "works" in the IO monad. When it moves from the line l <- ... to the next, IO - bind called.

You might think that since Haskell is lazy , l never evaluated. But " bind " always evaluates the previous command, right? Because the program generates a "file not found" error.

 main = do l <- mapM readFile [ "/tmp/notfound" ] return () 
+8
haskell ghc
source share
2 answers

You might think that since Haskell is lazy, l is never evaluated.

Yes, and he is never evaluated. However, due to the definition (>>=) in IO , the readFile "/tmp/notfound" action readFile "/tmp/notfound" is executed, which means that the runtime is trying to open the file. If there is no such file, the "File not found" error occurs. If such a file were opened, it would be open, but its contents will not be read until it is required. In this case, they are not required, so the contents will not be read.

What is evaluated here (and even performed) is the action that produces l . Since the file does not exist, this causes an error.

+15
source share

If you expand the do note in your code, you get:

 main = (mapM readFile ["/tmp/notfound"]) >>= (\l -> return ()) 

So yes, l never evaluated, but that does not mean that the mapM call mapM never evaluated. >>= always necessary to evaluate its left operand in order to get the value, at least to some extent (at least in the IO monad and in any other monad that comes to mind).

+9
source share

All Articles