Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Managing the IO monad

Tags:

haskell

I'm working on learning some Haskell (please excuse the newbie error)-

This routine errors out. My understanding of the do & <- syntax is that they extract the non-Monad type from the monad. So that understanding is flawed: what's the correct understanding here?

exister :: String -> Bool
exister path = do
  fileexist <- doesFileExist path 
  direxist <- doesDirectoryExist path
  return fileexist || direxist 

error

ghc -o joiner joiner.hs

joiner.hs:53:2:
    Couldn't match expected type `Bool' against inferred type `m Bool'
    In the first argument of `(||)', namely `return fileexist'
    In the expression: return fileexist || direxist
    In the expression:
        do { fileexist <- doesFileExist path;
             direxist <- doesDirectoryExist path;
               return fileexist || direxist }
like image 752
Paul Nathan Avatar asked Aug 01 '11 20:08

Paul Nathan


People also ask

What is an IO monad?

So, What is an IO Monad? IO Monad is simply a Monad which: Allows you to safely manipulate effects. Transform the effects into data and further manipulate it before it actually gets evaluated.

Is the IO monad pure?

“The IO monad does not make a function pure. It just makes it obvious that it's impure.”

Is IO a monad Haskell?

The IO type constructor provides a way to represent actions as Haskell values, so that we can manipulate them with pure functions. In the Prologue chapter, we anticipated some of the key features of this solution. Now that we also know that IO is a monad, we can wrap up the discussion we started there.

How does Haskell handle IO?

Haskell separates pure functions from computations where side effects must be considered by encoding those side effects as values of a particular type. Specifically, a value of type (IO a) is an action, which if executed would produce a value of type a .


2 Answers

First problem: The line return fileexist || direxist is parsed as (return fileexist) || direxist, and you can’t pass m Bool as the first argument of ||. Change it to return (fileexist || direxist).

Second problem: You claim the return type of exister is Bool, but the compiler infers that it must be IO Bool. Fix it. (The do and <- syntax let you extract the a value from an m a value, but only if you promise to return an m a value.)

like image 140
Josh Lee Avatar answered Nov 15 '22 08:11

Josh Lee


The type you've given exister :: String -> Bool is for a function that returns an ordinary, non-monadic Bool. The actions you're performing, doesFileExist path and doesDirectoryExist path have type IO Bool, so the m Bool in the error message really means IO Bool. If you change the type of exister to return IO Bool instead, the type will be what you intend.

Also, in the last line, you need some more parens: return (fileexist || direxist).

like image 44
acfoltzer Avatar answered Nov 15 '22 08:11

acfoltzer