module MontyHall where
import Probability
(Dist, Trans, RDist, uniform, mapD, (~.), idT, sequ, certainly, )
import List ( (\\) )
data Door = A | B | C
deriving (Eq,Ord,Show)
doors :: [Door]
doors = [A,B,C]
data State = Doors {prize :: Door, chosen :: Door, opened :: Door}
deriving (Eq,Ord,Show)
start :: State
start = Doors {prize=u,chosen=u,opened=u} where u=undefined
hide :: Trans State
hide s = uniform [s {prize = d} | d <- doors]
choose :: Trans State
choose s = uniform [s {chosen = d} | d <- doors]
open :: Trans State
open s = uniform [s {opened = d} | d <- doors \\ [prize s,chosen s]]
type Strategy = Trans State
switch :: Strategy
switch s = uniform [s {chosen = d} | d <- doors \\ [chosen s,opened s]]
stay :: Strategy
stay = idT
game :: Strategy -> Trans State
game s = sequ [hide,choose,open,s]
data Outcome = Win | Lose
deriving (Eq,Ord,Show)
result :: State -> Outcome
result s = if chosen s==prize s then Win else Lose
eval :: Strategy -> Dist Outcome
eval s = mapD result (game s start)
simEval :: Int -> Strategy -> RDist Outcome
simEval k s = mapD result `fmap` (k ~. game s) start
firstChoice :: Dist Outcome
firstChoice = uniform [Win,Lose,Lose]
switch' :: Trans Outcome
switch' Win = certainly Lose
switch' Lose = certainly Win