module Numeric.Probability.Example.DiceAccum where
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)