/
IxQueue.purs
94 lines (81 loc) · 2.77 KB
/
IxQueue.purs
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
module IxQueue
( IxQueue, newIxQueue, putIxQueue, injectIxQueue, onIxQueue, delIxQueue
) where
import Prelude
import Queue (Queue, newQueue, putQueue, onQueue, takeQueue)
import Data.Map (Map)
import Data.Map as Map
import Data.Maybe (Maybe (..))
import Data.Traversable (traverse_)
import Control.Monad.Eff (kind Effect, Eff)
import Control.Monad.Eff.Ref (REF, Ref, newRef, readRef, writeRef, modifyRef)
import Signal.Channel (CHANNEL)
newtype IxQueue (eff :: # Effect) k a = IxQueue (Ref (Map k (Queue eff a)))
newIxQueue :: forall eff k a
. Eff ( channel :: CHANNEL
, ref :: REF
| eff) (IxQueue (channel :: CHANNEL, ref :: REF | eff) k a)
newIxQueue = IxQueue <$> newRef Map.empty
putIxQueue :: forall eff k a
. Ord k
=> IxQueue (channel :: CHANNEL, ref :: REF | eff) k a
-> k
-> a
-> Eff ( channel :: CHANNEL
, ref :: REF
| eff) Unit
putIxQueue (IxQueue qsRef) k x = do
qs <- readRef qsRef
case Map.lookup k qs of
Nothing -> do
q <- newQueue
writeRef qsRef (Map.insert k q qs)
putQueue q x
Just q -> putQueue q x
-- | **Note**: if a Queue already exists in the IxQueue, then it _reads_
-- | all of the values in the existing queue before replacing it with the
-- | new one, then inserts the read entities.
injectIxQueue :: forall eff k a
. Ord k
=> IxQueue (channel :: CHANNEL, ref :: REF | eff) k a
-> k
-> Queue (channel :: CHANNEL, ref :: REF | eff) a
-> Eff ( channel :: CHANNEL
, ref :: REF
| eff) Unit
injectIxQueue (IxQueue qsRef) k q = do
qs <- readRef qsRef
case Map.lookup k qs of
Nothing ->
writeRef qsRef (Map.insert k q qs)
Just q' -> do
xs <- takeQueue q'
writeRef qsRef (Map.insert k q qs)
traverse_ (putQueue q) xs
onIxQueue :: forall eff k a
. Ord k
=> IxQueue (channel :: CHANNEL, ref :: REF | eff) k a
-> k
-> (a -> Eff ( channel :: CHANNEL
, ref :: REF
| eff) Unit)
-> Eff ( channel :: CHANNEL
, ref :: REF
| eff) Unit
onIxQueue (IxQueue qsRef) k f = do
qs <- readRef qsRef
case Map.lookup k qs of
Nothing -> do
q <- newQueue
writeRef qsRef (Map.insert k q qs)
onQueue q f
Just q -> onQueue q f
delIxQueue :: forall eff k a
. Ord k
=> IxQueue (channel :: CHANNEL, ref :: REF | eff) k a
-> k
-> Eff ( channel :: CHANNEL
, ref :: REF
| eff) Unit
delIxQueue (IxQueue qsRef) k =
modifyRef qsRef (Map.delete k)