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 }
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.
“The IO monad does not make a function pure. It just makes it obvious that it's impure.”
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.
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 .
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.)
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)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With