module Numeric.Probability.Example.Boys where
import qualified Numeric.Probability.Distribution as Dist
import Numeric.Probability.Distribution ((??), (?=<<), )
import Control.Monad (liftM2, )
type Probability = Rational
type Dist a = Dist.T Probability a
data Child = Boy | Girl
deriving (Eq,Ord,Show)
type Family = (Child, Child)
birth :: Dist Child
birth = Dist.uniform [Boy, Girl]
family :: Dist Family
family = liftM2 (,) birth birth
allBoys :: Dist.Event Family
allBoys (c0, c1) = (c0 == Boy && c1 == Boy)
existsBoy :: Dist.Event Family
existsBoy (c0, c1) = (c0 == Boy || c1 == Boy)
familyWithBoy :: Dist Family
familyWithBoy = existsBoy ?=<< family
twoBoys :: Probability
twoBoys = allBoys ?? familyWithBoy
countBoy :: Child -> Int
countBoy Boy = 1
countBoy Girl = 0
countBoys :: Family -> Int
countBoys (c0,c1) = countBoy c0 + countBoy c1
numBoys :: Dist Int
numBoys = Dist.map countBoys familyWithBoy