开发者

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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜