管理IO monad

时间:2011-08-01 20:40:21

标签: haskell

我正在研究一些Haskell(请原谅新手错误) -

此例程出错。我对do& amp;的理解< - 语法是他们从monad中提取非Monad类型。所以这种理解是有缺陷的:这里的正确理解是什么?

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

错误

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 }

2 个答案:

答案 0 :(得分:11)

第一个问题:行return fileexist || direxist被解析为(return fileexist) || direxist,您无法将m Bool作为||的第一个参数传递。将其更改为return (fileexist || direxist)

第二个问题:您声称返回类型existerBool,但编译器推断它必须是IO Bool。修理它。 (do<-语法允许您从a值中提取m a值,但前提是您保证返回m a值。)< / p>

答案 1 :(得分:5)

您给出的类型exister :: String -> Bool用于返回普通的非monadic Bool的函数。您正在执行的操作doesFileExist pathdoesDirectoryExist path的类型为IO Bool,因此错误消息中的m Bool实际上意味着IO Bool。如果您将exister的类型更改为返回IO Bool,则类型将是您想要的类型。

另外,在最后一行中,您需要更多的parens:return (fileexist || direxist)