1 module RandomizedMonad (
3 runRandom, runRandomStd, runRandomNewStd,
11 newtype Randomized a = Randomized (forall g. RandomGen g => (g -> a))
13 -- This implementation splits the RandomGen over and over.
14 -- It would also be possible to serialize everything and use a single RandomGen.
15 instance Monad Randomized where
16 ma >>= amb = Randomized (\g -> let
23 return x = Randomized (const x)
25 runRandom :: RandomGen g => g -> Randomized a -> a
26 runRandom g (Randomized fa) = fa g
29 runRandomStd :: Randomized a -> IO a
32 return $ runRandom g ra
34 runRandomNewStd :: Randomized a -> IO a
35 runRandomNewStd ra = do
37 return $ runRandom g ra
39 -- Monadic versions of random and randomR (to generate primitive-ish values)
40 mrandomR :: Random a => (a, a) -> Randomized a
41 mrandomR lohi = Randomized (\g -> fst (randomR lohi g))
42 mrandom :: Random a => Randomized a
43 mrandom = Randomized (\g -> fst (random g))
45 chooseCase :: Double -> [(Double, a)] -> a -> a
46 chooseCase val ifCs elseR = case ifCs of
48 (cutoff, theR):ifCt -> if val < cutoff
50 else chooseCase (val - cutoff) ifCt elseR
52 withProb :: [(Double, Randomized a)] -> Randomized a -> Randomized a
53 withProb ifCs elseR = do
55 chooseCase val ifCs elseR
57 -- Keep trying until we get what we want.
58 filterRandomized :: (a -> Bool) -> Randomized a -> Randomized a
59 filterRandomized f ra = do
61 if f a then return a else filterRandomized f ra