-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDice.curry
56 lines (41 loc) · 1.5 KB
/
Dice.curry
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
{-# OPTIONS_CYMAKE -X TypeClassExtensions #-}
module Dice where
import PFLP ( Dist(..), Probability (..)
, pure, filterDist, sumDist
, (<$>), (<*>))
import Distributions (uniform, uniform')
rollDices :: Int -> (_ -> Dist a) -> Dist [a]
rollDices n = replicateWith n _
die :: Dist Int
die = uniform [1..6]
-- probability to roll `value` `rounds` times
allTimesN :: Eq a => a -> Int -> Dist a -> Probability
allTimesN value rounds aDice =
let d = aDice
in dieNTimes (== rounds) rounds (== value) (\ () -> d)
-- sumDist
-- (filterDist ((== rounds) . length . filter (== value))
-- (rollDices rounds (\ () -> aDice)))
-- probability to roll `pValue x` `pCount y` times after `rounds` times
dieNTimes :: (Int -> Bool) -> Int -> (a -> Bool) -> (() -> Dist a) -> Probability
dieNTimes pCount rounds pValue aDice = sumDist
(filterDist (pCount . length . filter pValue)
(rollDices rounds aDice))
data Dice = One | Two | Three | Four | Five | Six
deriving (Bounded,Enum,Eq,Ord,Show)
die' :: Dist Dice
die' = uniform' _
-- -----------------------------------------------
-- Auxiliary Functions
-- -----------------------------------------------
replicateWith :: Int -> a -> (a -> Dist b) -> Dist [b]
replicateWith n v fd
| n == 0 = pure []
| otherwise = (:) <$> fd v <*> replicateWith (n - 1) v fd
{- Tests
-- uses commited-choice to reduce search tree
dieNTimes (== 9) 9 (==Six) (\() -> die')
(Prob 9.9229055e-8)
allTimesN Six 9 die'
(Prob 9.9229055e-8)
-}