module Numeric.Probability.Example.Dice where

import qualified Numeric.Probability.Distribution as Dist
import Numeric.Probability.Distribution ((??), )
import Control.Monad (liftM2, replicateM)


type Die = Int

type Probability = Rational
type Dist = Dist.T Probability

die :: Dist Die
die :: Dist Die
die = forall prob a. Fractional prob => Spread prob a
Dist.uniform [Die
1..Die
6]

-- | product of independent distributions
twoDice :: Dist (Die,Die)
twoDice :: Dist (Die, Die)
twoDice = forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) Dist Die
die Dist Die
die

dice :: Int -> Dist [Die]
dice :: Die -> Dist [Die]
dice = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) a. Applicative m => Die -> m a -> m [a]
replicateM Dist Die
die


twoSixes :: Probability
twoSixes :: Probability
twoSixes = (forall a. Eq a => a -> a -> Bool
==(Die
6,Die
6)) forall prob a. Num prob => Event a -> T prob a -> prob
?? Dist (Die, Die)
twoDice

{- |
@sixes p n@ computes the probability of getting
p sixes (@>1@, @==2@, ...) when rolling n dice
-}
sixes :: (Int -> Bool) -> Int -> Probability
sixes :: (Die -> Bool) -> Die -> Probability
sixes Die -> Bool
p Die
n = (Die -> Bool
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Die
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter (forall a. Eq a => a -> a -> Bool
==Die
6)) forall prob a. Num prob => Event a -> T prob a -> prob
?? Die -> Dist [Die]
dice Die
n

droll :: Dist Die
droll :: Dist Die
droll =
   forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall a. Num a => a -> a -> a
(+) (forall prob a. Fractional prob => Spread prob a
Dist.uniform [Die
0,Die
1]) Dist Die
die

g3 :: Probability
g3 :: Probability
g3 = (forall a. Ord a => a -> a -> Bool
>Die
3) forall prob a. Num prob => Event a -> T prob a -> prob
?? Dist Die
die

addTwo :: Dist Die
addTwo :: Dist Die
addTwo =
   forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall a. Num a => a -> a -> a
(+) Dist Die
die Dist Die
die