无法将bool转换为IO Bool

Dam*_*iii 0 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"
Run Code Online (Sandbox Code Playgroud)

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

我该怎么办?

lef*_*out 7

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

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

main = do
       [src] <- getArgs
       if src =~ owlFile
            then ...
            else ...
Run Code Online (Sandbox Code Playgroud)

也就是说,这种转换Bool -> IO Bool无论多么无用,都是可能的.实际上,对于任何monad 1来说 m,这是基本操作之一:

class Monad m where
  return :: a -> m a
Run Code Online (Sandbox Code Playgroud)

所以你原则上可以写

       resTestOwlFile <- return testOwlFile
Run Code Online (Sandbox Code Playgroud)

但不要.这总是相当于let resTestOwlFile = testOwlFile(由monad法律保证).


1 弱者Applicative实际上已经足够了.


GS *_*ica 6

问题是testOwlFile类型Bool,但<-符号期望一个IO something.

如果testOwlFile确实有类型IO Bool,那么resTestOwlFile将有类型Bool,你的代码将建立良好.

正如@ user2407038在注释中指出的那样,您可以使用let而不是<-在您定义的事物与您使用它定义的表达式具有相同类型时:

let resTestOwlFile = testOwlFile
Run Code Online (Sandbox Code Playgroud)

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

注意,更一般地说,<-符号期望m something任何m一个Monad类的实例,但在这种情况下m必须是IO因为你正在定义main函数,并且因为do块中的其他代码像getArgsprint.

  • 请为您的新问题使用新问题 (2认同)