无法匹配预期的类型

问题描述

| 我想做一些不同的事情,但是太长了,因此下面仅是示例:
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
    

解决方法

您需要使双方具有相同的类型,即
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
,else分支中的
do
块也是如此。     ,由于
canTest
具有副作用(即I / O有副作用),因此其返回类型为
IO Bool
,这有两个含义: 您不能直接在if谓词中测试其值,必须先“运行”操作,然后测试提取的值。 您编辑的“ 10”功能也必须位于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
结果是
Prelude> test \"5\" \"12\"
\"5\"
Prelude> test \"6\" \"12\"
bad value
\"12\"