-
Notifications
You must be signed in to change notification settings - Fork 104
/
Copy pathTChan.hs
72 lines (63 loc) · 1.81 KB
/
TChan.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
66
67
68
69
70
71
72
import Control.Concurrent.STM (STM, TVar, newTVar, readTVar, writeTVar, retry, atomically)
-- <<TChan
data TChan a = TChan (TVar (TVarList a))
(TVar (TVarList a))
type TVarList a = TVar (TList a)
data TList a = TNil | TCons a (TVarList a)
newTChan :: STM (TChan a)
newTChan = do
hole <- newTVar TNil
read <- newTVar hole
write <- newTVar hole
return (TChan read write)
readTChan :: TChan a -> STM a
readTChan (TChan readVar _) = do
listHead <- readTVar readVar
head <- readTVar listHead
case head of
TNil -> retry
TCons val tail -> do
writeTVar readVar tail
return val
writeTChan :: TChan a -> a -> STM ()
writeTChan (TChan _ writeVar) a = do
newListEnd <- newTVar TNil
listEnd <- readTVar writeVar
writeTVar writeVar newListEnd
writeTVar listEnd (TCons a newListEnd)
-- >>
-- <<dupTChan
dupTChan :: TChan a -> STM (TChan a)
dupTChan (TChan _ writeVar) = do
hole <- readTVar writeVar
newReadVar <- newTVar hole
return (TChan newReadVar writeVar)
-- >>
-- <<unGetTChan
unGetTChan :: TChan a -> a -> STM ()
unGetTChan (TChan readVar _) a = do
listHead <- readTVar readVar
newHead <- newTVar (TCons a listHead)
writeTVar readVar newHead
-- >>
-- <<isEmptyTChan
isEmptyTChan :: TChan a -> STM Bool
isEmptyTChan (TChan read _write) = do
listhead <- readTVar read
head <- readTVar listhead
case head of
TNil -> return True
TCons _ _ -> return False
-- >>
main = do
c <- atomically $ newTChan
atomically $ writeTChan c 'a'
atomically (readTChan c) >>= print
atomically (isEmptyTChan c) >>= print
atomically $ unGetTChan c 'a'
atomically (isEmptyTChan c) >>= print
atomically (readTChan c) >>= print
c2 <- atomically $ dupTChan c
atomically $ writeTChan c 'b'
atomically (readTChan c) >>= print
atomically (readTChan c2) >>= print