-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRandom.hs
65 lines (50 loc) · 1.54 KB
/
Random.hs
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
57
58
59
60
61
62
63
64
65
import State
import Control.Monad(liftM, liftM2)
import System.Random
rand :: IO Int
rand = getStdRandom (randomR (0, maxBound))
twoBadRandoms :: RandomGen g => g -> (Int, Int)
twoBadRandoms gen = (fst $ random gen, fst $ random gen)
twoGoodRandoms :: RandomGen g => g -> ((Int, Int), g)
twoGoodRandoms gen = let (a, gen') = random gen
(b, gen'')= random gen'
in ((a, b), gen'')
type RandomState a = State StdGen a
getRandom :: Random a => RandomState a
getRandom =
get >>= \gen ->
let (val, gen') = random gen in
put gen' >>
return val
runTwoRandoms :: IO (Int, Int)
runTwoRandoms = do
oldState <- getStdGen
let (result, newState) = runState getTwoRandoms oldState
setStdGen newState
return result
getTwoRandoms :: Random a => RandomState (a, a)
getTwoRandoms = liftM2 (,) getRandom getRandom
getRandom2 :: Random a => RandomState a
getRandom2 = do
gen <- get
let (val, gen') = random gen
put gen'
return val
data CountedRandom = CountedRandom {
crGen :: StdGen
, crCount :: Int
}
type CRState = State CountedRandom
getCountedRandom :: Random a => CRState a
getCountedRandom = do
st <- get
let (val, gen') = random (crGen st)
put CountedRandom {crGen = gen', crCount = crCount st + 1 }
return val
getCount :: CRState Int
getCount = crCount `liftM` get
putCount :: Int -> CRState ()
putCount a = get >>= \st ->
put st { crCount = a}
putCountModify :: Int -> CRState ()
putCountModify a = modify $ \st -> st {crCount = a }