moduleNumeric.Probability.Example.MontyHallwhereimportqualifiedNumeric.Probability.Distribution asDistimportqualifiedNumeric.Probability.Transition asTransimportNumeric.Probability.Simulation ((~.) ,)importNumeric.Probability.Percentage (Dist ,RDist ,Trans ,)importqualifiedNumeric.Probability.Monad asMonadExtimportData.List((\\)){- no Random instance for Rational
type Probability = Rational
type Dist a = Dist.T Probability a
type RDist a = Rnd.Distribution Probability a
type Trans a = Transition Probability a
-}dataDoor =A |B |C deriving(Door -> Door -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Door -> Door -> Bool
$c/= :: Door -> Door -> Bool
== :: Door -> Door -> Bool
$c== :: Door -> Door -> Bool
Eq,Eq Door
Door -> Door -> Bool
Door -> Door -> Ordering
Door -> Door -> Door
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Door -> Door -> Door
$cmin :: Door -> Door -> Door
max :: Door -> Door -> Door
$cmax :: Door -> Door -> Door
>= :: Door -> Door -> Bool
$c>= :: Door -> Door -> Bool
> :: Door -> Door -> Bool
$c> :: Door -> Door -> Bool
<= :: Door -> Door -> Bool
$c<= :: Door -> Door -> Bool
< :: Door -> Door -> Bool
$c< :: Door -> Door -> Bool
compare :: Door -> Door -> Ordering
$ccompare :: Door -> Door -> Ordering
Ord,Int -> Door -> ShowS
[Door] -> ShowS
Door -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Door] -> ShowS
$cshowList :: [Door] -> ShowS
show :: Door -> String
$cshow :: Door -> String
showsPrec :: Int -> Door -> ShowS
$cshowsPrec :: Int -> Door -> ShowS
Show)doors ::[Door ]doors :: [Door]
doors =[Door
A ,Door
B ,Door
C ]dataState =Doors {State -> Door
prize ::Door ,State -> Door
chosen ::Door ,State -> Door
opened ::Door }deriving(State -> State -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: State -> State -> Bool
$c/= :: State -> State -> Bool
== :: State -> State -> Bool
$c== :: State -> State -> Bool
Eq,Eq State
State -> State -> Bool
State -> State -> Ordering
State -> State -> State
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: State -> State -> State
$cmin :: State -> State -> State
max :: State -> State -> State
$cmax :: State -> State -> State
>= :: State -> State -> Bool
$c>= :: State -> State -> Bool
> :: State -> State -> Bool
$c> :: State -> State -> Bool
<= :: State -> State -> Bool
$c<= :: State -> State -> Bool
< :: State -> State -> Bool
$c< :: State -> State -> Bool
compare :: State -> State -> Ordering
$ccompare :: State -> State -> Ordering
Ord,Int -> State -> ShowS
[State] -> ShowS
State -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [State] -> ShowS
$cshowList :: [State] -> ShowS
show :: State -> String
$cshow :: State -> String
showsPrec :: Int -> State -> ShowS
$cshowsPrec :: Int -> State -> ShowS
Show)-- | initial configuration of the game statusstart ::State start :: State
start =Doors {prize :: Door
prize =forall {a}. a
u ,chosen :: Door
chosen =forall {a}. a
u ,opened :: Door
opened =forall {a}. a
u }whereu :: a
u =forall a. HasCallStack => a
undefined{- |
Steps of the game:
 (1) hide the prize
 (2) choose a door
 (3) open a non-open door, not revealing the prize
 (4) apply strategy: switch or stay
-}hide ::Trans State hide :: Trans State
hide State
s =forall prob a. Fractional prob => Spread prob a
Dist.uniform [State
s {prize :: Door
prize =Door
d }|Door
d <-[Door]
doors ]choose ::Trans State choose :: Trans State
choose State
s =forall prob a. Fractional prob => Spread prob a
Dist.uniform [State
s {chosen :: Door
chosen =Door
d }|Door
d <-[Door]
doors ]open ::Trans State open :: Trans State
open State
s =forall prob a. Fractional prob => Spread prob a
Dist.uniform [State
s {opened :: Door
opened =Door
d }|Door
d <-[Door]
doors forall a. Eq a => [a] -> [a] -> [a]
\\[State -> Door
prize State
s ,State -> Door
chosen State
s ]]typeStrategy =Trans State switch ::Strategy switch :: Trans State
switch State
s =forall prob a. Fractional prob => Spread prob a
Dist.uniform [State
s {chosen :: Door
chosen =Door
d }|Door
d <-[Door]
doors forall a. Eq a => [a] -> [a] -> [a]
\\[State -> Door
chosen State
s ,State -> Door
opened State
s ]]stay ::Strategy stay :: Trans State
stay =forall prob a. Num prob => T prob a
Trans.id game ::Strategy ->Trans State game :: Trans State -> Trans State
game Trans State
s =forall (m :: * -> *) a. Monad m => [a -> m a] -> a -> m a
MonadExt.compose [Trans State
hide ,Trans State
choose ,Trans State
open ,Trans State
s ]-- * Playing the gamedataOutcome =Win |Lose deriving(Outcome -> Outcome -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Outcome -> Outcome -> Bool
$c/= :: Outcome -> Outcome -> Bool
== :: Outcome -> Outcome -> Bool
$c== :: Outcome -> Outcome -> Bool
Eq,Eq Outcome
Outcome -> Outcome -> Bool
Outcome -> Outcome -> Ordering
Outcome -> Outcome -> Outcome
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Outcome -> Outcome -> Outcome
$cmin :: Outcome -> Outcome -> Outcome
max :: Outcome -> Outcome -> Outcome
$cmax :: Outcome -> Outcome -> Outcome
>= :: Outcome -> Outcome -> Bool
$c>= :: Outcome -> Outcome -> Bool
> :: Outcome -> Outcome -> Bool
$c> :: Outcome -> Outcome -> Bool
<= :: Outcome -> Outcome -> Bool
$c<= :: Outcome -> Outcome -> Bool
< :: Outcome -> Outcome -> Bool
$c< :: Outcome -> Outcome -> Bool
compare :: Outcome -> Outcome -> Ordering
$ccompare :: Outcome -> Outcome -> Ordering
Ord,Int -> Outcome -> ShowS
[Outcome] -> ShowS
Outcome -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Outcome] -> ShowS
$cshowList :: [Outcome] -> ShowS
show :: Outcome -> String
$cshow :: Outcome -> String
showsPrec :: Int -> Outcome -> ShowS
$cshowsPrec :: Int -> Outcome -> ShowS
Show)result ::State ->Outcome result :: State -> Outcome
result State
s =ifState -> Door
chosen State
s forall a. Eq a => a -> a -> Bool
==State -> Door
prize State
s thenOutcome
Win elseOutcome
Lose eval ::Strategy ->Dist Outcome eval :: Trans State -> Dist Outcome
eval Trans State
s =forall prob b a.
(Num prob, Ord b) =>
(a -> b) -> T prob a -> T prob b
Dist.map State -> Outcome
result (Trans State -> Trans State
game Trans State
s State
start )simEval ::Int->Strategy ->RDist Outcome simEval :: Int -> Trans State -> RDist Outcome
simEval Int
k Trans State
s =forall prob b a.
(Num prob, Ord b) =>
(a -> b) -> T prob a -> T prob b
Dist.map State -> Outcome
result forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap`(Int
k forall (c :: * -> *) prob a.
(C c, Fractional prob, Ord prob, Random prob, Ord a) =>
Int -> (a -> c a) -> Transition prob a
~. Trans State -> Trans State
game Trans State
s )State
start -- * Alternative modelingfirstChoice ::Dist Outcome firstChoice :: Dist Outcome
firstChoice =forall prob a. Fractional prob => Spread prob a
Dist.uniform [Outcome
Win ,Outcome
Lose ,Outcome
Lose ]switch' ::Trans Outcome switch' :: Trans Outcome
switch' Outcome
Win =forall prob a. Num prob => T prob a
Dist.certainly Outcome
Lose switch' Outcome
Lose =forall prob a. Num prob => T prob a
Dist.certainly Outcome
Win -- * Play the game the monadic waytypeStrategyM =Door ->Door ->Door stayM ::StrategyM stayM :: Door -> Door -> Door
stayM Door
chosenDoor Door
_openedDoor =Door
chosenDoor switchM ::StrategyM switchM :: Door -> Door -> Door
switchM Door
chosenDoor Door
openedDoor =let[Door
finalDoor ]=[Door]
doors forall a. Eq a => [a] -> [a] -> [a]
\\[Door
chosenDoor ,Door
openedDoor ]inDoor
finalDoor evalM ::StrategyM ->Dist Outcome evalM :: (Door -> Door -> Door) -> Dist Outcome
evalM Door -> Door -> Door
chooseFinalDoor =doDoor
prizeDoor <-forall prob a. Fractional prob => Spread prob a
Dist.uniform [Door]
doors Door
chosenDoor <-forall prob a. Fractional prob => Spread prob a
Dist.uniform [Door]
doors Door
openedDoor <-forall prob a. Fractional prob => Spread prob a
Dist.uniform ([Door]
doors forall a. Eq a => [a] -> [a] -> [a]
\\[Door
prizeDoor ,Door
chosenDoor ])forall (m :: * -> *) a. Monad m => a -> m a
return(ifDoor -> Door -> Door
chooseFinalDoor Door
chosenDoor Door
openedDoor forall a. Eq a => a -> a -> Bool
==Door
prizeDoor thenOutcome
Win elseOutcome
Lose )

AltStyle によって変換されたページ (->オリジナル) /