module Numeric.Probability.Example.DiceAccum where
import qualified Numeric.Probability.Example.Dice as Dice
import qualified Numeric.Probability.Random as Rnd
import qualified Numeric.Probability.Distribution as Dist
import qualified Numeric.Probability.Transition as Trans
import qualified Numeric.Probability.Monad as MonadExt
import Numeric.Probability.Trace (Trace)
import Numeric.Probability.Example.Dice (Die, )
type Score = Int
die :: Fractional prob => Dist.T prob Die
die = Dist.uniform [1..6]
roll :: Fractional prob => Trans.T prob (Maybe Score)
roll =
maybe
(return Nothing)
(\score -> flip fmap die $
\spots ->
if spots == 3
then Nothing
else Just (score + spots))
continue :: Score -> Bool
continue scoreInt =
let score = fromIntegral scoreInt :: Rational
in Dist.expected
(Dist.uniform (0 : map (score+) [1,2,4,5,6])) > score
strategy :: Fractional prob => Trans.T prob (Maybe Score)
strategy s0 =
maybe
(return Nothing)
(\score ->
if continue score
then roll s0
else return s0) s0
game :: Fractional prob => Dist.T prob (Maybe Score)
game =
Trans.compose (replicate 18 strategy) (Just 0)
walk :: Int -> IO (Trace (Maybe Score))
walk n =
Rnd.run $
MonadExt.walk n
(Rnd.change (roll :: Trans.T Double (Maybe Score)))
(Just 0)