@@ -28,21 +28,63 @@ module Data.StrMap
2828 foldMap ,
2929 foldM ,
3030 foldMaybe ,
31- all
31+ all ,
32+
33+ thawST ,
34+ freezeST ,
35+ runST
3236 ) where
3337
3438import qualified Prelude as P
3539
40+ import Control.Monad.Eff (Eff (), runPure )
41+ import qualified Control.Monad.ST as ST
3642import qualified Data.Array as A
3743import Data.Maybe
3844import Data.Function
3945import Data.Tuple
40- import Data.Foldable (Foldable , foldl , foldr )
46+ import Data.Foldable (Foldable , foldl , foldr , for_ )
4147import Data.Monoid
4248import Data.Monoid.All
49+ import qualified Data.StrMap.ST as SM
4350
4451foreign import data StrMap :: * -> *
4552
53+ foreign import _copy " " "
54+ function _copy(m) {
55+ var r = {};
56+ for (var k in m)
57+ r[k] = m[k]
58+ return r;
59+ }" " " :: forall a . StrMap a -> StrMap a
60+
61+ foreign import _copyEff " " "
62+ function _copyEff(m) {
63+ return function () {
64+ return _copy(m);
65+ };
66+ }" " " :: forall a b h r . a -> Eff (st :: ST.ST h | r ) b
67+
68+ thawST :: forall a h r . StrMap a -> Eff (st :: ST.ST h | r ) (SM.STStrMap h a )
69+ thawST = _copyEff
70+
71+ freezeST :: forall a h r . SM.STStrMap h a -> Eff (st :: ST.ST h | r ) (StrMap a )
72+ freezeST = _copyEff
73+
74+ foreign import runST " " "
75+ function runST(f) {
76+ return f;
77+ }" " " :: forall a r . (forall h . Eff (st :: ST.ST h | r ) (SM.STStrMap h a )) -> Eff r (StrMap a )
78+
79+ pureST :: forall a b . (forall h e . Eff (st :: ST.ST h | e ) (SM.STStrMap h a )) -> StrMap a
80+ pureST f = runPure (runST f)
81+
82+ mutate :: forall a b . (forall h e . SM.STStrMap h a -> Eff (st :: ST.ST h | e ) b ) -> StrMap a -> StrMap a
83+ mutate f m = pureST (do
84+ s <- thawST m
85+ f s
86+ P .return s)
87+
4688foreign import _fmapStrMap
4789 " function _fmapStrMap(m0, f) {\
4890 \ var m = {};\
@@ -137,7 +179,10 @@ foreign import size "function size(m) {\
137179 \}" :: forall a . StrMap a -> Number
138180
139181singleton :: forall a . String -> a -> StrMap a
140- singleton k v = insert k v empty
182+ singleton k v = pureST (do
183+ s <- SM .new
184+ SM .poke s k v
185+ P .return s)
141186
142187foreign import _lookup
143188 " function _lookup(no, yes, k, m) {\
@@ -150,26 +195,8 @@ lookup = runFn4 _lookup Nothing Just
150195member :: forall a . String -> StrMap a -> Boolean
151196member = runFn4 _lookup false (P .const true )
152197
153- foreign import _cloneStrMap
154- " function _cloneStrMap(m0) { \
155- \ var m = {}; \
156- \ for (var k in m0) {\
157- \ m[k] = m0[k];\
158- \ }\
159- \ return m;\
160- \}" :: forall a . (StrMap a ) -> (StrMap a )
161-
162- foreign import _unsafeInsertStrMap
163- " function _unsafeInsertStrMap(m, k, v) { \
164- \ m[k] = v; \
165- \ return m; \
166- \}" :: forall a . Fn3 (StrMap a ) String a (StrMap a )
167-
168- _unsafeInsert :: forall a . StrMap a -> String -> a -> StrMap a
169- _unsafeInsert = runFn3 _unsafeInsertStrMap
170-
171198insert :: forall a . String -> a -> StrMap a -> StrMap a
172- insert k v m = _unsafeInsert (_cloneStrMap m) k v
199+ insert k v = mutate (\s -> SM .poke s k v)
173200
174201foreign import _unsafeDeleteStrMap
175202 " function _unsafeDeleteStrMap(m, k) { \
@@ -178,7 +205,7 @@ foreign import _unsafeDeleteStrMap
178205 \}" :: forall a . Fn2 (StrMap a ) String (StrMap a )
179206
180207delete :: forall a . String -> StrMap a -> StrMap a
181- delete k m = runFn2 _unsafeDeleteStrMap (_cloneStrMap m) k
208+ delete k = mutate (\s -> SM .delete s k)
182209
183210alter :: forall a . (Maybe a -> Maybe a ) -> String -> StrMap a -> StrMap a
184211alter f k m = case f (k `lookup` m) of
@@ -188,6 +215,12 @@ alter f k m = case f (k `lookup` m) of
188215update :: forall a . (a -> Maybe a ) -> String -> StrMap a -> StrMap a
189216update f k m = alter (maybe Nothing f) k m
190217
218+ fromList :: forall a . [Tuple String a ] -> StrMap a
219+ fromList l = pureST (do
220+ s <- SM .new
221+ for_ l (\(Tuple k v) -> SM .poke s k v)
222+ P .return s)
223+
191224foreign import _collect
192225 " function _collect(f) {\
193226 \ return function (m) {\
@@ -201,9 +234,6 @@ foreign import _collect
201234toList :: forall a . StrMap a -> [Tuple String a ]
202235toList = _collect Tuple
203236
204- fromList :: forall a . [Tuple String a ] -> StrMap a
205- fromList = foldl (\m (Tuple k v) -> _unsafeInsert m k v) (_cloneStrMap empty)
206-
207237foreign import keys
208238 " var keys = Object.keys || _collect(function (k) {\
209239 \ return function () { return k; };\
@@ -214,7 +244,7 @@ values = _collect (\_ v -> v)
214244
215245-- left-biased
216246union :: forall a . StrMap a -> StrMap a -> StrMap a
217- union m1 m2 = fold _unsafeInsert (_cloneStrMap m2) m1
247+ union m = mutate (\s -> foldM SM .poke s m)
218248
219249unions :: forall a . [StrMap a ] -> StrMap a
220250unions = foldl union empty
@@ -223,5 +253,4 @@ map :: forall a b. (a -> b) -> StrMap a -> StrMap b
223253map = P .(<$>)
224254
225255instance semigroupStrMap :: (P.Semigroup a ) => P.Semigroup (StrMap a ) where
226- (<>) m1 m2 = fold f (_cloneStrMap m1) m2 where
227- f m k v2 = _unsafeInsert m k (runFn4 _lookup v2 (\v1 -> v1 P .<> v2) k m)
256+ (<>) m1 m2 = mutate (\s -> foldM (\s k v2 -> SM .poke s k (runFn4 _lookup v2 (\v1 -> v1 P .<> v2) k m2)) s m1) m2
0 commit comments