0

I am receiving "parse error in if statement: missing required else clause" on line 202. I believe I am using the correct if-then-else syntax for haskell. But let me know what's wrong. Thanks

I've tried shifting the various if statements around but to no avail

playerMove p e =
 if ((getPHealth p) > 0) then
  do 
     putStrLn (showOpts2)
     move <- getLine
     if (move == 0) then
      do 
        let e = Enemy (getEDescription e) ((getEHealth e) - (getPAttack p)) (getEAttack e)
        putStrLn ("you dealt " + (getPAttack p) + " damage to your foe")
        enemyMove p e
     if (move == 1) then
      do 
        let p = Player (getPHealth) (getPAttack) (getPScore) True
        return p
        else return p
     else return p
 else return p
1
  • 2
    Like the error says, you're missing an else. It should be before if (move == 1). Commented Oct 15, 2019 at 3:20

3 Answers 3

1

It's this bit:

if (move == 0) then
 do 
   let e = Enemy (getEDescription e) ((getEHealth e) - (getPAttack p)) (getEAttack e)
   putStrLn ("you dealt " + (getPAttack p) + " damage to your foe")
   enemyMove p e
-- No else here before indentation is reduced
if (move == 1) then

There are a couple other things I notice here. Check the type of move; does move == 0 make sense? Instead of horrendously nested if/then/else, Haskell provides a nice switch-like construct, detailed at the bottom of this Learn You a Haskell page.

Sign up to request clarification or add additional context in comments.

Comments

0

I shifted the innermost if statement forward, and it seems to compile. I don't know if this keeps the original intent of the program.

Also, getLine returns a string, but you are comparing the output to an Int. And ++ is string concatenation, not +.

I hope this helps. Good luck!

playerMove p e =
 if ((getPHealth p) > 0) then
  do
     putStrLn (showOpts2)
     move <- getLine
     if (move == "0") then
      do 
        let e = Enemy (getEDescription e) ((getEHealth e) - (getPAttack p)) (getEAttack e)
        putStrLn ("you dealt " ++ (getPAttack p) ++ " damage to your foe")
        enemyMove p e
        if (move == "1") then
          do 
            let p = Player (getPHealth) (getPAttack) (getPScore) True
            return p
        else return p
     else return p
 else return p

2 Comments

It probably doesn't keep the original intent, now that I actually read it I see that move can't equal "0" and "1".
Thanks so much for your help!
0

Using a "case of" construct instead of an "if then else" one:

As mentioned by Khuldraeseth na'Barya, you could use a case of construct. This would allow the extra case of move being neither 0 nor 1 to fit nicely.

It is a bit difficult to fill in the blanks as we haven't seen your types, but this code compiles, under reasonable assumptions for the object types:

playerMove :: Move -> Move -> IO Move
playerMove p e =
  if ((getPHealth p) > 0) then
    do 
      putStrLn (showOpts2)
      moveStr <- getLine
      let move = (read moveStr)::Integer
      case move of
        0 -> do 
               let e = Enemy (getEDescription e) ((getEHealth e) - (getPAttack p)) (getEAttack e)
               putStrLn $ ("you dealt " ++ (show (getPAttack p)) ++ " damage to your foe")
               enemyMove p e
        1 -> do
               let p = Player (getPHealth) (getPAttack) (getPScore) True
               return p
        _ -> do
               return p -- what if move is neither 0 nor 1 ??
  else
    return p

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.