Skip to content

Commit 3857c6c

Browse files
authored
Add Map.catMaybes function (#25)
* Add catMaybes function * Add catMaybes to Set
1 parent 201b304 commit 3857c6c

File tree

5 files changed

+31
-2
lines changed

5 files changed

+31
-2
lines changed

src/Data/Map.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module Data.Map
55

66
import Prelude
77

8-
import Data.Map.Internal (Map, alter, checkValid, delete, empty, filter, filterKeys, filterWithKey, findMax, findMin, foldSubmap, fromFoldable, fromFoldableWith, fromFoldableWithIndex, insert, insertWith, isEmpty, isSubmap, lookup, lookupGE, lookupGT, lookupLE, lookupLT, member, pop, showTree, singleton, size, submap, toUnfoldable, toUnfoldableUnordered, union, unionWith, unions, intersection, intersectionWith, difference, update, values, mapMaybeWithKey, mapMaybe)
8+
import Data.Map.Internal (Map, alter, catMaybes, checkValid, delete, empty, filter, filterKeys, filterWithKey, findMax, findMin, foldSubmap, fromFoldable, fromFoldableWith, fromFoldableWithIndex, insert, insertWith, isEmpty, isSubmap, lookup, lookupGE, lookupGT, lookupLE, lookupLT, member, pop, showTree, singleton, size, submap, toUnfoldable, toUnfoldableUnordered, union, unionWith, unions, intersection, intersectionWith, difference, update, values, mapMaybeWithKey, mapMaybe)
99
import Data.Set (Set)
1010
import Unsafe.Coerce (unsafeCoerce)
1111

src/Data/Map/Internal.purs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ module Data.Map.Internal
4444
, filter
4545
, mapMaybeWithKey
4646
, mapMaybe
47+
, catMaybes
4748
) where
4849

4950
import Prelude
@@ -689,3 +690,8 @@ mapMaybeWithKey f = foldrWithIndex (\k a acc → maybe acc (\b -> insert k b acc
689690
-- | function returns `Nothing`.
690691
mapMaybe :: forall k a b. Ord k => (a -> Maybe b) -> Map k a -> Map k b
691692
mapMaybe = mapMaybeWithKey <<< const
693+
694+
-- | Filter a map of optional values, keeping only the key/value pairs which
695+
-- | contain a value, creating a new map.
696+
catMaybes :: forall k v. Ord k => Map k (Maybe v) -> Map k v
697+
catMaybes = mapMaybe identity

src/Data/Set.purs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ module Data.Set
2626
, intersection
2727
, filter
2828
, mapMaybe
29+
, catMaybes
2930
) where
3031

3132
import Prelude hiding (map)
@@ -190,3 +191,7 @@ filter f (Set s) = Set (M.filterWithKey (\k _ -> f k) s)
190191
-- | function returns `Nothing`.
191192
mapMaybe :: forall a b. Ord b => (a -> Maybe b) -> Set a -> Set b
192193
mapMaybe f = foldr (\a acc -> maybe acc (\b -> insert b acc) (f a)) empty
194+
195+
-- | Filter a set of optional values, discarding values that contain `Nothing`
196+
catMaybes :: forall a. Ord a => Set (Maybe a) -> Set a
197+
catMaybes = mapMaybe identity

test/Test/Data/Map.purs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import Data.Tuple (Tuple(..), fst, uncurry)
1818
import Effect (Effect)
1919
import Effect.Console (log)
2020
import Partial.Unsafe (unsafePartial)
21-
import Test.QuickCheck ((<?>), (===), quickCheck, quickCheck')
21+
import Test.QuickCheck ((<?>), (<=?), (===), quickCheck, quickCheck')
2222
import Test.QuickCheck.Arbitrary (class Arbitrary, arbitrary)
2323
import Test.QuickCheck.Gen (elements, oneOf)
2424

@@ -370,3 +370,15 @@ mapTests = do
370370
quickCheck \(TestMap m :: TestMap Int Int) ->
371371
let outList = foldrWithIndex (\i a b -> (Tuple i a) : b) Nil m
372372
in outList == sort outList
373+
374+
log "catMaybes creates a new map of size less than or equal to the original"
375+
quickCheck \(TestMap m :: TestMap Int (Maybe Int)) -> do
376+
let result = M.catMaybes m
377+
M.size result <=? M.size m
378+
379+
log "catMaybes drops key/value pairs with Nothing values"
380+
quickCheck \(TestMap m :: TestMap Int Int) -> do
381+
let maybeMap = M.alter (const $ Just Nothing) 1 $ map Just m
382+
let result = M.catMaybes maybeMap
383+
let expected = M.delete 1 m
384+
result === expected

test/Test/Data/Set.purs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module Test.Data.Set where
22

33
import Prelude
44

5+
import Data.Maybe (Maybe(..))
56
import Data.Set (Set)
67
import Data.Set as S
78
import Effect (Effect)
@@ -25,3 +26,8 @@ setTests = do
2526
s2 = S.fromFoldable [2,4,6,8,10]
2627
s3 = S.fromFoldable [2,4]
2728
assert $ S.intersection s1 s2 == s3
29+
30+
log "catMaybes - drops Nothing values"
31+
do let s1 = S.fromFoldable [Just 1,Just 2,Just 3,Nothing]
32+
s2 = S.fromFoldable [1,2,3]
33+
assert $ S.catMaybes s1 == s2

0 commit comments

Comments
 (0)