-
-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathtransactions.hs
61 lines (47 loc) · 1.55 KB
/
transactions.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
import Control.Monad.STM
import Control.Concurrent.STM.TVar
import Control.Concurrent (forkIO, threadDelay)
import System.Random.MWC (createSystemRandom, uniformR)
import qualified Data.Sequence as Seq
import Control.Monad (forever)
import Data.Foldable (asum, for_)
import Data.Traversable (for)
main =
do
accountList <-
for [1..10] $ \_ ->
atomically (newTVar (100 :: Integer))
let
accountSeq = Seq.fromList accountList
randomAccount rng =
do
i <- uniformR (1, Seq.length accountSeq) rng
return (Seq.index accountSeq (i - 1))
for_ [1..500] $ \_ ->
forkIO $
do
rng <- createSystemRandom
forever $
do
d <- uniformR (10, 50) rng
threadDelay d
sender <- randomAccount rng
recipient <- randomAccount rng
amount <-
do
x <- uniformR (1, 10) rng
return (toInteger (x :: Int))
atomically $
asum
[ do
modifyTVar' sender (\x -> x - amount)
readTVar sender >>= \x -> check (x >= 0)
modifyTVar' recipient (\x -> x + amount)
, return ()
]
for_ [1..4] $ \_ ->
do
threadDelay 500000
balances <- atomically (for accountList readTVar)
putStrLn (show balances)
putStrLn ("Total: " ++ show (sum balances))