Managing the IO monad
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 <- doesD开发者_运维百科irectoryExist path;
return fileexist || direxist }
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)
.
精彩评论