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