Parse error on input 'if' when trying to use a condition inside a do block

前端 未结 3 2044
被撕碎了的回忆
被撕碎了的回忆 2020-12-20 18:37

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

相关标签:
3条回答
  • 2020-12-20 19:18

    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"
    
    0 讨论(0)
  • 2020-12-20 19:23

    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)
    
    0 讨论(0)
  • 2020-12-20 19:42

    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.

    0 讨论(0)
提交回复
热议问题