Search code examples
haskellmonadsdo-notation

If/then/else in do statements (Haskell)


I've got a block of code that I've written which doesn't compile because the if/then/else block isn't set out in a way the compiler understands, however I can't figure out how to rewrite it so that it can.

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)

basically the function uniform will divide by zero if the list is empty, so I need a way to catch this and return the empty list before carrying on with the do statement. Any advice?


Solution

  • You can wrap the remaining commands in a new 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)
    

    I want to warn you, however, that if you do this a multiple times, your code will staircase outward and become unreadable. To solve this, you can break apart functions, or use a monad for error checking.