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 :: forall prob. Fractional prob => T prob Score
die = forall prob a. Fractional prob => Spread prob a
Dist.uniform [Score
1..Score
6]
roll :: Fractional prob => Trans.T prob (Maybe Score)
roll :: forall prob. Fractional prob => T prob (Maybe Score)
roll =
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing)
(\Score
score -> forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall prob. Fractional prob => T prob Score
die forall a b. (a -> b) -> a -> b
$
\Score
spots ->
if Score
spots forall a. Eq a => a -> a -> Bool
== Score
3
then forall a. Maybe a
Nothing
else forall a. a -> Maybe a
Just (Score
score forall a. Num a => a -> a -> a
+ Score
spots))
continue :: Score -> Bool
continue :: Score -> Bool
continue Score
scoreInt =
let score :: Rational
score = forall a b. (Integral a, Num b) => a -> b
fromIntegral Score
scoreInt :: Rational
in forall a. Num a => T a a -> a
Dist.expected
(forall prob a. Fractional prob => Spread prob a
Dist.uniform (Rational
0 forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map (Rational
scoreforall a. Num a => a -> a -> a
+) [Rational
1,Rational
2,Rational
4,Rational
5,Rational
6])) forall a. Ord a => a -> a -> Bool
> Rational
score
strategy :: Fractional prob => Trans.T prob (Maybe Score)
strategy :: forall prob. Fractional prob => T prob (Maybe Score)
strategy Maybe Score
s0 =
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing)
(\Score
score ->
if Score -> Bool
continue Score
score
then forall prob. Fractional prob => T prob (Maybe Score)
roll Maybe Score
s0
else forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Score
s0) Maybe Score
s0
game :: Fractional prob => Dist.T prob (Maybe Score)
game :: forall prob. Fractional prob => T prob (Maybe Score)
game =
forall prob a. (Num prob, Ord a) => [T prob a] -> T prob a
Trans.compose (forall a. Score -> a -> [a]
replicate Score
18 forall prob. Fractional prob => T prob (Maybe Score)
strategy) (forall a. a -> Maybe a
Just Score
0)
walk :: Int -> IO (Trace (Maybe Score))
walk :: Score -> IO (Trace (Maybe Score))
walk Score
n =
forall a. T a -> IO a
Rnd.run forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a.
Monad m =>
Score -> (a -> m a) -> a -> m [a]
MonadExt.walk Score
n
(forall prob a.
(Num prob, Ord prob, Random prob) =>
T prob a -> Change a
Rnd.change (forall prob. Fractional prob => T prob (Maybe Score)
roll :: Trans.T Double (Maybe Score)))
(forall a. a -> Maybe a
Just Score
0)