无法将bool转换为IO Bool

时间:2014-06-02 00:07:48

标签: haskell

我正在尝试做一个返回true或false的函数。

owlFile = ".+\\.owl"

testOwlFile src = src =~ owlFile :: Bool

我需要在我的阻止上使用:

main = do
       [src] <- getArgs
       resTestOwlFile <- testOwlFile
       if resTestOwlFile
            then do ontology <- runX(readDocument [withValidate no,withRemoveWS yes ] src >>> getontology)
            else print "error"

但我的错误是Couldn't match excepted type IO BOOL with actual type Bool In the return type of a call of "testOwlFile"

我能为此做些什么?

2 个答案:

答案 0 :(得分:7)

一般来说,请避免考虑“转换”。有时您实际上需要这样做,但通常情况下,如果您正确使用,类型系统会在正确的位置为您提供正确的类型。

IO Bool 不是一个布尔值,但是一个可能与副作用一起产生布尔值的动作。那么为什么你要将一个非常好的纯值“转换”成这样一个动作,一个实际上没有做任何类型的东西的动作呢?这没有多大意义。正如已经说过的,正确的做法是直接使用该值;我只是把它直接放在if条件下:

main = do
       [src] <- getArgs
       if src =~ owlFile
            then ...
            else ...

尽管如此,这种转换Bool -> IO Bool无论多么无用,都是可能的。实际上,对于任何monad 1 m,这是基本操作之一:

class Monad m where
  return :: a -> m a

所以你原则上可以写

       resTestOwlFile <- return testOwlFile

但不要。这总是等同于let resTestOwlFile = testOwlFile(由monad laws保证)。

<小时/> 1 较弱的Applicative实际上已经足够了。

答案 1 :(得分:6)

问题是testOwlFile的类型为Bool,但<-符号需要IO something

如果testOwlFile确实有IO Bool类型,则resTestOwlFile的类型为Bool,您的代码就可以正常运行。

正如@ user2407038在评论中指出的那样,当你定义的东西与你定义它的表达式具有相同的类型时,你可以使用let而不是<-

let resTestOwlFile = testOwlFile

或者您可以直接在下一行的testOwlFile语句中使用if

请注意,对于<-类的m something类的任何mMonad符号通常需要m,但在这种情况下{{1} }}必须是IO,因为您正在定义main函数,并且因为do块中的其他代码,例如getArgsprint。< / p>