Skip to content
This repository was archived by the owner on Oct 4, 2020. It is now read-only.

Commit a8c4742

Browse files
committed
Merge pull request #42 from LiamGoodacre/master
Couple new foldable functions to `Data.Map`
2 parents fc6a29c + 3c76244 commit a8c4742

File tree

6 files changed

+146
-42
lines changed

6 files changed

+146
-42
lines changed

docs/Data/Map.md

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ data Map k v
1313

1414
##### Instances
1515
``` purescript
16-
instance eqMap :: (Eq k, Eq v) => Eq (Map k v)
17-
instance showMap :: (Show k, Show v) => Show (Map k v)
18-
instance ordMap :: (Ord k, Ord v) => Ord (Map k v)
19-
instance semigroupMap :: (Ord k) => Semigroup (Map k v)
20-
instance monoidMap :: (Ord k) => Monoid (Map k v)
21-
instance functorMap :: Functor (Map k)
22-
instance foldableMap :: Foldable (Map k)
23-
instance traversableMap :: (Ord k) => Traversable (Map k)
16+
(Eq k, Eq v) => Eq (Map k v)
17+
(Show k, Show v) => Show (Map k v)
18+
(Ord k, Ord v) => Ord (Map k v)
19+
(Ord k) => Semigroup (Map k v)
20+
(Ord k) => Monoid (Map k v)
21+
Functor (Map k)
22+
Foldable (Map k)
23+
(Ord k) => Traversable (Map k)
2424
```
2525

2626
#### `showTree`
@@ -113,29 +113,47 @@ update :: forall k v. (Ord k) => (v -> Maybe v) -> k -> Map k v -> Map k v
113113

114114
Update or delete the value for a key in a map
115115

116+
#### `fromFoldable`
117+
118+
``` purescript
119+
fromFoldable :: forall f k v. (Ord k, Foldable f) => f (Tuple k v) -> Map k v
120+
```
121+
122+
Convert any foldable collection of key/value pairs to a map.
123+
On key collision, later values take precedence over earlier ones.
124+
125+
#### `fromFoldableWith`
126+
127+
``` purescript
128+
fromFoldableWith :: forall f k v. (Ord k, Foldable f) => (v -> v -> v) -> f (Tuple k v) -> Map k v
129+
```
130+
131+
Convert any foldable collection of key/value pairs to a map.
132+
On key collision, the values are configurably combined.
133+
116134
#### `toList`
117135

118136
``` purescript
119137
toList :: forall k v. Map k v -> List (Tuple k v)
120138
```
121139

122-
Convert a map to an array of key/value pairs
140+
Convert a map to a list of key/value pairs
123141

124142
#### `fromList`
125143

126144
``` purescript
127145
fromList :: forall k v. (Ord k) => List (Tuple k v) -> Map k v
128146
```
129147

130-
Create a map from an array of key/value pairs
148+
Create a map from a list of key/value pairs
131149

132150
#### `fromListWith`
133151

134152
``` purescript
135153
fromListWith :: forall k v. (Ord k) => (v -> v -> v) -> List (Tuple k v) -> Map k v
136154
```
137155

138-
Create a map from an array of key/value pairs, using the specified function
156+
Create a map from a list of key/value pairs, using the specified function
139157
to combine values for duplicate keys.
140158

141159
#### `keys`
@@ -144,15 +162,15 @@ to combine values for duplicate keys.
144162
keys :: forall k v. Map k v -> List k
145163
```
146164

147-
Get an array of the keys contained in a map
165+
Get a list of the keys contained in a map
148166

149167
#### `values`
150168

151169
``` purescript
152170
values :: forall k v. Map k v -> List v
153171
```
154172

155-
Get an array of the values contained in a map
173+
Get a list of the values contained in a map
156174

157175
#### `unionWith`
158176

docs/Data/StrMap.md

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ data StrMap :: * -> *
1616

1717
##### Instances
1818
``` purescript
19-
instance functorStrMap :: Functor StrMap
20-
instance foldableStrMap :: Foldable StrMap
21-
instance traversableStrMap :: Traversable StrMap
22-
instance eqStrMap :: (Eq a) => Eq (StrMap a)
23-
instance showStrMap :: (Show a) => Show (StrMap a)
24-
instance semigroupStrMap :: (Semigroup a) => Semigroup (StrMap a)
25-
instance monoidStrMap :: (Semigroup a) => Monoid (StrMap a)
19+
Functor StrMap
20+
Foldable StrMap
21+
Traversable StrMap
22+
(Eq a) => Eq (StrMap a)
23+
(Show a) => Show (StrMap a)
24+
(Semigroup a) => Semigroup (StrMap a)
25+
(Semigroup a) => Monoid (StrMap a)
2626
```
2727

2828
#### `thawST`
@@ -185,21 +185,38 @@ update :: forall a. (a -> Maybe a) -> String -> StrMap a -> StrMap a
185185

186186
Remove or update a value for a key in a map
187187

188+
#### `fromFoldable`
189+
190+
``` purescript
191+
fromFoldable :: forall f a. (Foldable f) => f (Tuple String a) -> StrMap a
192+
```
193+
194+
Create a map from a foldable collection of key/value pairs
195+
196+
#### `fromFoldableWith`
197+
198+
``` purescript
199+
fromFoldableWith :: forall f a. (Foldable f) => (a -> a -> a) -> f (Tuple String a) -> StrMap a
200+
```
201+
202+
Create a map from a foldable collection of key/value pairs, using the
203+
specified function to combine values for duplicate keys.
204+
188205
#### `fromList`
189206

190207
``` purescript
191208
fromList :: forall a. List (Tuple String a) -> StrMap a
192209
```
193210

194-
Create a map from an array of key/value pairs
211+
Create a map from a list of key/value pairs
195212

196213
#### `fromListWith`
197214

198215
``` purescript
199216
fromListWith :: forall a. (a -> a -> a) -> List (Tuple String a) -> StrMap a
200217
```
201218

202-
Create a map from an array of key/value pairs, using the specified function
219+
Create a map from a list of key/value pairs, using the specified function
203220
to combine values for duplicate keys.
204221

205222
#### `toList`
@@ -208,7 +225,7 @@ to combine values for duplicate keys.
208225
toList :: forall a. StrMap a -> List (Tuple String a)
209226
```
210227

211-
Convert a map into an array of key/value pairs
228+
Convert a map into a list of key/value pairs
212229

213230
#### `keys`
214231

@@ -224,7 +241,7 @@ Get an array of the keys in a map
224241
values :: forall a. StrMap a -> List a
225242
```
226243

227-
Get an array of the values in a map
244+
Get a list of the values in a map
228245

229246
#### `union`
230247

src/Data/Map.purs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ module Data.Map
1010
, checkValid
1111
, insert
1212
, lookup
13+
, fromFoldable
14+
, fromFoldableWith
1315
, toList
1416
, fromList
1517
, fromListWith
@@ -239,30 +241,40 @@ alter f k m = case f (k `lookup` m) of
239241
update :: forall k v. (Ord k) => (v -> Maybe v) -> k -> Map k v -> Map k v
240242
update f k m = alter (maybe Nothing f) k m
241243

242-
-- | Convert a map to an array of key/value pairs
244+
-- | Convert any foldable collection of key/value pairs to a map.
245+
-- | On key collision, later values take precedence over earlier ones.
246+
fromFoldable :: forall f k v. (Ord k, Foldable f) => f (Tuple k v) -> Map k v
247+
fromFoldable = foldl (\m (Tuple k v) -> insert k v m) empty
248+
249+
-- | Convert any foldable collection of key/value pairs to a map.
250+
-- | On key collision, the values are configurably combined.
251+
fromFoldableWith :: forall f k v. (Ord k, Foldable f) => (v -> v -> v) -> f (Tuple k v) -> Map k v
252+
fromFoldableWith f = foldl (\m (Tuple k v) -> alter (combine v) k m) empty where
253+
combine v (Just v') = Just $ f v v'
254+
combine v Nothing = Just v
255+
256+
-- | Convert a map to a list of key/value pairs
243257
toList :: forall k v. Map k v -> List (Tuple k v)
244258
toList Leaf = Nil
245259
toList (Two left k v right) = toList left ++ pure (Tuple k v) ++ toList right
246260
toList (Three left k1 v1 mid k2 v2 right) = toList left ++ pure (Tuple k1 v1) ++ toList mid ++ pure (Tuple k2 v2) ++ toList right
247261

248-
-- | Create a map from an array of key/value pairs
262+
-- | Create a map from a list of key/value pairs
249263
fromList :: forall k v. (Ord k) => List (Tuple k v) -> Map k v
250-
fromList = foldl (\m (Tuple k v) -> insert k v m) empty
264+
fromList = fromFoldable
251265

252-
-- | Create a map from an array of key/value pairs, using the specified function
266+
-- | Create a map from a list of key/value pairs, using the specified function
253267
-- | to combine values for duplicate keys.
254268
fromListWith :: forall k v. (Ord k) => (v -> v -> v) -> List (Tuple k v) -> Map k v
255-
fromListWith f = foldl (\m (Tuple k v) -> alter (combine v) k m) empty where
256-
combine v (Just v') = Just $ f v v'
257-
combine v Nothing = Just v
269+
fromListWith = fromFoldableWith
258270

259-
-- | Get an array of the keys contained in a map
271+
-- | Get a list of the keys contained in a map
260272
keys :: forall k v. Map k v -> List k
261273
keys Leaf = Nil
262274
keys (Two left k _ right) = keys left ++ pure k ++ keys right
263275
keys (Three left k1 _ mid k2 _ right) = keys left ++ pure k1 ++ keys mid ++ pure k2 ++ keys right
264276

265-
-- | Get an array of the values contained in a map
277+
-- | Get a list of the values contained in a map
266278
values :: forall k v. Map k v -> List v
267279
values Leaf = Nil
268280
values (Two left _ v right) = values left ++ pure v ++ values right

src/Data/StrMap.purs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ module Data.StrMap
1313
, insert
1414
, lookup
1515
, toList
16+
, fromFoldable
17+
, fromFoldableWith
1618
, fromList
1719
, fromListWith
1820
, delete
@@ -181,33 +183,44 @@ alter f k m = case f (k `lookup` m) of
181183
update :: forall a. (a -> Maybe a) -> String -> StrMap a -> StrMap a
182184
update f k m = alter (maybe Nothing f) k m
183185

184-
-- | Create a map from an array of key/value pairs
185-
fromList :: forall a. L.List (Tuple String a) -> StrMap a
186-
fromList l = pureST (do
186+
-- | Create a map from a foldable collection of key/value pairs
187+
fromFoldable :: forall f a. (Foldable f) =>
188+
f (Tuple String a) -> StrMap a
189+
fromFoldable l = pureST (do
187190
s <- SM.new
188191
for_ l (\(Tuple k v) -> SM.poke s k v)
189192
return s)
190193

191194
foreign import _lookupST :: forall a h r z. Fn4 z (a -> z) String (SM.STStrMap h a) (Eff (st :: ST.ST h | r) z)
192195

193-
-- | Create a map from an array of key/value pairs, using the specified function
194-
-- | to combine values for duplicate keys.
195-
fromListWith :: forall a. (a -> a -> a) -> L.List (Tuple String a) -> StrMap a
196-
fromListWith f l = pureST (do
196+
-- | Create a map from a foldable collection of key/value pairs, using the
197+
-- | specified function to combine values for duplicate keys.
198+
fromFoldableWith :: forall f a. (Foldable f) =>
199+
(a -> a -> a) -> f (Tuple String a) -> StrMap a
200+
fromFoldableWith f l = pureST (do
197201
s <- SM.new
198202
for_ l (\(Tuple k v) -> runFn4 _lookupST v (f v) k s >>= SM.poke s k)
199203
return s)
200204

205+
-- | Create a map from a list of key/value pairs
206+
fromList :: forall a. L.List (Tuple String a) -> StrMap a
207+
fromList = fromFoldable
208+
209+
-- | Create a map from a list of key/value pairs, using the specified function
210+
-- | to combine values for duplicate keys.
211+
fromListWith :: forall a. (a -> a -> a) -> L.List (Tuple String a) -> StrMap a
212+
fromListWith = fromFoldableWith
213+
201214
foreign import _collect :: forall a b . (String -> a -> b) -> StrMap a -> Array b
202215

203-
-- | Convert a map into an array of key/value pairs
216+
-- | Convert a map into a list of key/value pairs
204217
toList :: forall a. StrMap a -> L.List (Tuple String a)
205218
toList = L.toList <<< _collect Tuple
206219

207220
-- | Get an array of the keys in a map
208221
foreign import keys :: forall a. StrMap a -> Array String
209222

210-
-- | Get an array of the values in a map
223+
-- | Get a list of the values in a map
211224
values :: forall a. StrMap a -> L.List a
212225
values = L.toList <<< _collect (\_ v -> v)
213226

test/Test/Data/Map.purs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,28 @@ mapTests = do
154154
log "Singleton to list"
155155
quickCheck $ \k v -> M.toList (M.singleton k v :: M.Map SmallKey Int) == singleton (Tuple k v)
156156

157+
log "fromFoldable [] = empty"
158+
quickCheck (M.fromFoldable [] == (M.empty :: M.Map Unit Unit)
159+
<?> "was not empty")
160+
161+
log "fromFoldable & key collision"
162+
do
163+
let nums = M.fromFoldable [Tuple 0 "zero", Tuple 1 "what", Tuple 1 "one"]
164+
quickCheck (M.lookup 0 nums == Just "zero" <?> "invalid lookup - 0")
165+
quickCheck (M.lookup 1 nums == Just "one" <?> "invalid lookup - 1")
166+
quickCheck (M.lookup 2 nums == Nothing <?> "invalid lookup - 2")
167+
168+
log "fromFoldableWith const [] = empty"
169+
quickCheck (M.fromFoldableWith const [] == (M.empty :: M.Map Unit Unit)
170+
<?> "was not empty")
171+
172+
log "fromFoldableWith (+) & key collision"
173+
do
174+
let nums = M.fromFoldableWith (+) [Tuple 0 1, Tuple 1 1, Tuple 1 1]
175+
quickCheck (M.lookup 0 nums == Just 1 <?> "invalid lookup - 0")
176+
quickCheck (M.lookup 1 nums == Just 2 <?> "invalid lookup - 1")
177+
quickCheck (M.lookup 2 nums == Nothing <?> "invalid lookup - 2")
178+
157179
log "toList . fromList = id"
158180
quickCheck $ \arr -> let f x = M.toList (M.fromList x)
159181
in f (f arr) == f (arr :: List (Tuple SmallKey Int)) <?> show arr

test/Test/Data/StrMap.purs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,28 @@ strMapTests = do
8282
log "Singleton to list"
8383
quickCheck $ \k v -> M.toList (M.singleton k v :: M.StrMap Int) == singleton (Tuple k v)
8484

85+
log "fromFoldable [] = empty"
86+
quickCheck (M.fromFoldable [] == (M.empty :: M.StrMap Unit)
87+
<?> "was not empty")
88+
89+
log "fromFoldable & key collision"
90+
do
91+
let nums = M.fromFoldable [Tuple "0" "zero", Tuple "1" "what", Tuple "1" "one"]
92+
quickCheck (M.lookup "0" nums == Just "zero" <?> "invalid lookup - 0")
93+
quickCheck (M.lookup "1" nums == Just "one" <?> "invalid lookup - 1")
94+
quickCheck (M.lookup "2" nums == Nothing <?> "invalid lookup - 2")
95+
96+
log "fromFoldableWith const [] = empty"
97+
quickCheck (M.fromFoldableWith const [] == (M.empty :: M.StrMap Unit)
98+
<?> "was not empty")
99+
100+
log "fromFoldableWith (+) & key collision"
101+
do
102+
let nums = M.fromFoldableWith (+) [Tuple "0" 1, Tuple "1" 1, Tuple "1" 1]
103+
quickCheck (M.lookup "0" nums == Just 1 <?> "invalid lookup - 0")
104+
quickCheck (M.lookup "1" nums == Just 2 <?> "invalid lookup - 1")
105+
quickCheck (M.lookup "2" nums == Nothing <?> "invalid lookup - 2")
106+
85107
log "toList . fromList = id"
86108
quickCheck $ \arr -> let f x = M.toList (M.fromList x)
87109
in f (f arr) == f (arr :: List (Tuple String Int)) <?> show arr

0 commit comments

Comments
 (0)