user12217943
user12217943

Reputation: 3

parse error in if statement: missing required else clause in Haskell code

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

Upvotes: 0

Views: 190

Answers (3)

jpmarinier
jpmarinier

Reputation: 4733

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

Upvotes: 0

Garrison
Garrison

Reputation: 386

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

Upvotes: 0

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.

Upvotes: 1

Related Questions