From: Ross Paterson Date: Thu, 17 Aug 2006 23:50:41 +0000 (+0000) Subject: add mapMaybe and mapEither, plus WithKey variants X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=5d30f3426e4153aebb7022f7dbda05647a3cb891;p=haskell-directory.git add mapMaybe and mapEither, plus WithKey variants --- diff --git a/Data/IntMap.hs b/Data/IntMap.hs index 652a23e..daf85a0 100644 --- a/Data/IntMap.hs +++ b/Data/IntMap.hs @@ -121,6 +121,11 @@ module Data.IntMap ( , partition , partitionWithKey + , mapMaybe + , mapMaybeWithKey + , mapEither + , mapEitherWithKey + , split , splitLookup @@ -847,6 +852,36 @@ partitionWithKey pred t | otherwise -> (Nil,t) Nil -> (Nil,Nil) +-- | /O(n)/. Map values and collect the 'Just' results. +mapMaybe :: (a -> Maybe b) -> IntMap a -> IntMap b +mapMaybe f m + = mapMaybeWithKey (\k x -> f x) m + +-- | /O(n)/. Map keys\/values and collect the 'Just' results. +mapMaybeWithKey :: (Key -> a -> Maybe b) -> IntMap a -> IntMap b +mapMaybeWithKey f (Bin p m l r) + = bin p m (mapMaybeWithKey f l) (mapMaybeWithKey f r) +mapMaybeWithKey f (Tip k x) = case f k x of + Just y -> Tip k y + Nothing -> Nil +mapMaybeWithKey f Nil = Nil + +-- | /O(n)/. Map values and separate the 'Left' and 'Right' results. +mapEither :: (a -> Either b c) -> IntMap a -> (IntMap b, IntMap c) +mapEither f m + = mapEitherWithKey (\k x -> f x) m + +-- | /O(n)/. Map keys\/values and separate the 'Left' and 'Right' results. +mapEitherWithKey :: (Key -> a -> Either b c) -> IntMap a -> (IntMap b, IntMap c) +mapEitherWithKey f (Bin p m l r) + = (bin p m l1 r1, bin p m l2 r2) + where + (l1,l2) = mapEitherWithKey f l + (r1,r2) = mapEitherWithKey f r +mapEitherWithKey f (Tip k x) = case f k x of + Left y -> (Tip k y, Nil) + Right z -> (Nil, Tip k z) +mapEitherWithKey f Nil = (Nil, Nil) -- | /O(log n)/. The expression (@'split' k map@) is a pair @(map1,map2)@ -- where all keys in @map1@ are lower than @k@ and all keys in diff --git a/Data/Map.hs b/Data/Map.hs index 269fe5e..56b25e1 100644 --- a/Data/Map.hs +++ b/Data/Map.hs @@ -123,6 +123,11 @@ module Data.Map ( , partition , partitionWithKey + , mapMaybe + , mapMaybeWithKey + , mapEither + , mapEitherWithKey + , split , splitLookup @@ -870,6 +875,33 @@ partitionWithKey p (Bin _ kx x l r) (l1,l2) = partitionWithKey p l (r1,r2) = partitionWithKey p r +-- | /O(n)/. Map values and collect the 'Just' results. +mapMaybe :: Ord k => (a -> Maybe b) -> Map k a -> Map k b +mapMaybe f m + = mapMaybeWithKey (\k x -> f x) m + +-- | /O(n)/. Map keys\/values and collect the 'Just' results. +mapMaybeWithKey :: Ord k => (k -> a -> Maybe b) -> Map k a -> Map k b +mapMaybeWithKey f Tip = Tip +mapMaybeWithKey f (Bin _ kx x l r) = case f kx x of + Just y -> join kx y (mapMaybeWithKey f l) (mapMaybeWithKey f r) + Nothing -> merge (mapMaybeWithKey f l) (mapMaybeWithKey f r) + +-- | /O(n)/. Map values and separate the 'Left' and 'Right' results. +mapEither :: Ord k => (a -> Either b c) -> Map k a -> (Map k b, Map k c) +mapEither f m + = mapEitherWithKey (\k x -> f x) m + +-- | /O(n)/. Map keys\/values and separate the 'Left' and 'Right' results. +mapEitherWithKey :: Ord k => + (k -> a -> Either b c) -> Map k a -> (Map k b, Map k c) +mapEitherWithKey f Tip = (Tip, Tip) +mapEitherWithKey f (Bin _ kx x l r) = case f kx x of + Left y -> (join kx y l1 r1, merge l2 r2) + Right z -> (merge l1 r1, join kx z l2 r2) + where + (l1,l2) = mapEitherWithKey f l + (r1,r2) = mapEitherWithKey f r {-------------------------------------------------------------------- Mapping