Reputation: 91
I would like to do something different but it would be too long so below is only example:
test x y = if x == "5" then x
else do putStrLn "bad value"; y
so if x == 5 it should return x, else it should print 'bad value' and return y - how can I do that in haskell ?
edit:
Why this code returns error: "couldn't match expected type bool with actual type 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
Upvotes: 2
Views: 6678
Reputation: 11
Because canTest
has side-effects (i.e. does I/O), its return type is IO Bool
, which has two implications:
Your edited test
function must also be in the IO monad, as you cannot escape IO. (Unless very carefully with 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
Results in
Prelude> test "5" "12"
"5"
Prelude> test "6" "12"
bad value
"12"
Upvotes: 0
Reputation: 3558
You need to make both sides have the same type, namely IO String
. For this you need to use return
to lift the values into the monad, i.e.
test :: String -> String -> IO String
test x y = if x == "5"
then return x
else do putStrLn "bad value"
return y
Now return x
has the type IO String
, and so does the do
block in the else branch.
Upvotes: 6