I have the following code and I already tried multiple ways to write this, but I can\'t make it work. What I need is to use an if
condition inside a do
In Haskell everything after =
is an expression, and expressions usually have values. Even conditional statement is expression as well as putStr "hi"
and they have their (return) values. In case of if
return value is value of corresponding branch (then or else). In case of putStr "hi"
it's somewhat more involved, I won't explain it here (see IO and monads)
So the correct way to write your code would be the following:
palin :: IO ()
palin = do line <- getLine
if True
then putStr line
else return ()
-- this return has nothing to do with return in python
-- basically it means "do nothing"
In Haskell, an if-else expression does not mean "if true, execute foo; else, execute bar", but "if true, the value is foo; else, the value is bar". For that reason, you can't omit the else
, much in the same way that you can't when using the ternary if operator (conditon ? foo : bar
) in other languages. In your case, the then
part is a value of type IO ()
, so you need an else
with the same type. As you do not want antyhing to actually happen if the condition is false, the most immediate solution is using the dummy IO ()
value, return ()
:
palin :: IO ()
palin
= do line <- getLine
putStr line
if True
then putStr line
else return ()
You can also use the when
function from Control.Monad
, which has the same effect:
import Control.Monad
palin :: IO ()
palin
= do line <- getLine
putStr line
when True (putStr line)
You're missing an else.
palin :: IO ()
palin = do
line <- getLine
putStr line --Probably better to use putStrLn?
if True then putStr line else putStr "hi" --Also consider putStrLn here?
You need to provide an value, if you're coming from Python, then think about something like
a = "dogs" if 1 < 0 else "cats"
here, you need to provide the else as without it the variable assignment wouldn't run.