If/then/else в операторах do (Haskell)

У меня есть блок кода, который я написал, который не компилируется, потому что блок if/then/else не изложен так, как понимает компилятор, однако я не могу понять, как его переписать. что может.

playRandomly board = do
                 let vMoves = getValidMoves board board
                 if vMoves == [] then return [] else
                 rMove <- uniform vMoves
                 let Just nBoard = runMove board rMove
                 rest <- playRandomly nBoard
                 return (rMove : rest)

в основном функция uniform будет делить на ноль, если список пуст, поэтому мне нужен способ поймать это и вернуть пустой список, прежде чем продолжить оператор do. Любой совет?


person Harvey Adcock    schedule 30.11.2014    source источник
comment
Ради интереса я вставил альтернативный рестайлинг здесь. Не помещая это в качестве ответа, потому что на самом деле это не отвечает на вопрос о том, какой отступ заставляет это работать?   -  person Daniel Wagner    schedule 30.11.2014


Ответы (1)


Вы можете обернуть оставшиеся команды в новый do

playRandomly board = do
             let vMoves = getValidMoves board board
             if vMoves == [] 
               then return [] 
               else do
                 rMove <- uniform vMoves
                 let Just nBoard = runMove board rMove
                 rest <- playRandomly nBoard
                 return (rMove : rest)

Однако я хочу предупредить вас, что если вы сделаете это несколько раз, ваш код будет ступенчатым и станет нечитаемым. Чтобы решить эту проблему, вы можете разбить функции или использовать монаду для проверки ошибок.

person jamshidh    schedule 30.11.2014
comment
Это тот самый, спасибо. Думал о том, чтобы разделить его, но в любом случае это была такая маленькая функция, я надеялся, что будет простое встроенное решение, как вы предоставили. - person Harvey Adcock; 30.11.2014