1

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?

Harvey Adcock
  • 929
  • 1
  • 7
  • 16
  • Just for fun, I've pasted an alternate restyling [here](http://lpaste.net/115385). Not putting this as an answer because, well, it doesn't really answer the question of "what indentation makes this work?". – Daniel Wagner Nov 30 '14 at 20:40

1 Answers1

5

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.

jamshidh
  • 12,002
  • 17
  • 31
  • That's the one, thanks. Did think about splitting it up, but was such a small function anyway I had hoped there would be an easy in-line solution like you provided. – Harvey Adcock Nov 30 '14 at 18:21