1 module RandomizedMonad (
3 runRandom, runRandomStd, runRandomNewStd,
10 import Data.Array.IArray
14 newtype Randomized a = Randomized (forall g. RandomGen g => (g -> a))
16 -- This implementation splits the RandomGen over and over.
17 -- It would also be possible to serialize everything and use a single RandomGen.
18 instance Monad Randomized where
19 ma >>= amb = Randomized (\g -> let
26 return x = Randomized (const x)
28 runRandom :: RandomGen g => g -> Randomized a -> a
29 runRandom g (Randomized fa) = fa g
32 runRandomStd :: Randomized a -> IO a
35 return $ runRandom g ra
37 runRandomNewStd :: Randomized a -> IO a
38 runRandomNewStd ra = do
40 return $ runRandom g ra
42 -- Monadic versions of random and randomR (to generate primitive-ish values)
43 mrandomR :: Random a => (a, a) -> Randomized a
44 mrandomR lohi = Randomized (\g -> fst (randomR lohi g))
45 mrandom :: Random a => Randomized a
46 mrandom = Randomized (\g -> fst (random g))
48 chooseCase :: Double -> [(Double, a)] -> a -> a
49 chooseCase val ifCs elseR = case ifCs of
51 (cutoff, theR):ifCt -> if val < cutoff
53 else chooseCase (val - cutoff) ifCt elseR
55 withProb :: [(Double, Randomized a)] -> Randomized a -> Randomized a
56 withProb ifCs elseR = do
58 chooseCase val ifCs elseR
60 -- Keep trying until we get what we want.
61 filterRandomized :: (a -> Bool) -> Randomized a -> Randomized a
62 filterRandomized f ra = do
64 if f a then return a else filterRandomized f ra
66 -- Randomized array with elements chosen independently following a given
67 -- randomized element.
68 indRandomArray :: (IArray a e, Ix i) =>
69 (i, i) -> Randomized e -> Randomized (a i e)
70 indRandomArray bds rElement = do
71 list <- sequence $ replicate (rangeSize bds) rElement
72 return (listArray bds list)