ошибка синтаксического анализа в операторе if: отсутствует обязательное условие else в коде Haskell - PullRequest
0 голосов
/ 15 октября 2019

Я получаю «ошибка синтаксического анализа в операторе if: отсутствует обязательное условие else» в строке 202. Мне кажется, я использую правильный синтаксис if-then-else для haskell. Но дай мне знать, что не так. Спасибо

Я пытался изменить различные операторы if, но безрезультатно

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

Ответы [ 3 ]

1 голос
/ 15 октября 2019

Вот этот бит:

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

Здесь я заметил еще пару вещей. Проверьте тип move;move == 0 имеет смысл? Вместо ужасающе вложенного if/then/else, Haskell предоставляет симпатичную switch -подобную конструкцию, подробно описанную в нижней части этой страницы Learn You a Haskell .

0 голосов
/ 15 октября 2019

Используя конструкцию "case of" вместо конструкции "if then else":

Как упоминалось Khuldraeseth na'Barya, вы можете использовать конструкцию case of. Это позволило бы дополнительному случаю перемещения быть ни 0, ни 1., чтобы он хорошо подходил.

Немного трудно заполнить пробелы , так как мы не видели ваши типы, но этокод компилируется при разумных допущениях для типов объектов:

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
0 голосов
/ 15 октября 2019

Я сдвинул самый внутренний оператор if вперед, и он, кажется, компилируется. Я не знаю, соответствует ли это первоначальному замыслу программы.

Также, getLine возвращает строку, но вы сравниваете вывод с Int. И ++ - это конкатенация строк, а не +.

Надеюсь, это поможет. Удачи!

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
...