<div>Hello Everyone,<br></div><div><br></div><div>In the HPFFP book, there's a homework problem where you're supposed to refactor a recursive function that rolls dice to return the number of rolls it takes to reach or exceed an input sum and the list of die that occurred. As practice, decided to take the solution and implement it using the State monad:<br></div><div><br></div><div>-- Refactor rollsCountLoggged to use State<br></div><div>--                limit sum count StdGen [Die]<br></div><div>type RollsState = (Int, Int, Int, StdGen, [Die])<br></div><div>--                count [Die]<br></div><div>type RollsValue = (Int, [Die])<br></div><div><br></div><div>runRolls :: State RollsState RollsValue<br></div><div>runRolls = do<br></div><div>  (l, s, c, sg, xs) <- get<br></div><div>  if (s >= l) then<br></div><div>    return (c, reverse xs)<br></div><div>  else<br></div><div>    do<br></div><div>      let (d, ng) = randomR (1, 6) sg<br></div><div>      put (l, s + d, c + 1, ng, intToDie d : xs)<br></div><div>      runRolls<br></div><div>                <br></div><div>rollsCountState :: Int -> IO ()<br></div><div>rollsCountState n = print $ evalState (runRolls) (n, 0, 0, mkStdGen 0, [])<br></div><div><br></div><div>I'm wondering if that 'do' block under the else is a not so great stylistic choice. If the 'let' and 'put' is moved above the 'if', then that's just an unnecessary call at the end. Or is it just the nature of running inside a monad?<br></div><div><br></div><div>Thank You,<br></div><div>Andrea<br></div><div><br></div><div><br></div><div><br></div><div><br></div><div class="protonmail_signature_block "><div class="protonmail_signature_block-user protonmail_signature_block-empty"><br></div><div class="protonmail_signature_block-proton ">Sent with <a href="https://protonmail.com">ProtonMail</a> Secure Email.<br></div></div><div><br></div>