无法匹配预期的类型

时间:2011-05-24 15:07:59

标签: haskell

我想做一些与众不同的事情但是时间过长所以下面只是例子:

test x y = if x == "5" then x
           else do putStrLn "bad value"; y

所以如果x == 5它应该返回x,否则它应该打印'bad value'并返回y - 我怎样才能在haskell中这样做?


修改

为什么此代码返回错误:“无法将预期类型bool与实际类型IO bool匹配”?

canTest :: String -> IO Bool
canTest x = if x == "5" then return True
           else do putStrLn "bad value"; return False

test x y = if canTest x then x
           else y

2 个答案:

答案 0 :(得分:6)

您需要使双方具有相同的类型,即IO String。为此,您需要使用return将值提升到monad中,即

test :: String -> String -> IO String
test x y = if x == "5"
             then return x
             else do putStrLn "bad value"
                     return y

现在return x的类型为IO String,其他分支中的do块也是如此。

答案 1 :(得分:0)

因为canTest有副作用(即I / O),其返回类型为IO Bool,这有两个含义:

  1. 您无法直接在if谓词中测试其值,您必须先“运行”该操作,然后测试提取的值。
  2. 您编辑的test函数也必须位于IO monad中,因为您无法转义IO。 (除非非常谨慎地使用unsafePerformIO

    canTest :: String -> IO Bool
    canTest x = if x == "5"
                  then return True
                  else do putStrLn "bad value"; return False
    
    test :: String -> String -> IO String
    test x y = do xCanTest <- canTest x
                  if xCanTest
                    then return x
                    else return y
    
  3. 结果

    Prelude> test "5" "12"
    "5"
    Prelude> test "6" "12"
    bad value
    "12"