witherable 0.1.2.1 → 0.1.2.2
raw patch · 2 files changed
+33/−18 lines, 2 files
Files
- src/Data/Witherable.hs +32/−17
- witherable.cabal +1/−1
src/Data/Witherable.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP #-} +{-# LANGUAGE CPP, DeriveFunctor, DeriveFoldable, DeriveTraversable, StandaloneDeriving, UndecidableInstances, FlexibleContexts #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Witherable @@ -6,10 +6,9 @@ -- License : BSD3 -- -- Maintainer : Fumiaki Kinoshita <fumiexcel@gmail.com> --- Stability : experimental +-- Stability : provisional -- Portability : non-portable -- --- This module generalizes filterable containers. ----------------------------------------------------------------------------- module Data.Witherable where import qualified Data.Maybe as Maybe @@ -45,8 +44,9 @@ -- -- @t . 'wither' f = 'wither' (t . f)@ -- --- Minimal complete definition: `wither` or `catMaybes`. --- The default definitions can be overriden for efficiency. +-- Minimal complete definition: `wither` or `mapMaybe` or `catMaybes`. +-- The default definitions can be overridden for efficiency. + class T.Traversable t => Witherable t where wither :: Applicative f => (a -> f (Maybe b)) -> t a -> f (t b) @@ -87,34 +87,34 @@ {-# INLINABLE wither #-} instance Witherable [] where - wither f = fmap Maybe.catMaybes . T.traverse f - {-# INLINABLE wither #-} + wither f = go where + go (x:xs) = maybe id (:) <$> f x <*> go xs + go [] = pure [] + {-# INLINE wither #-} + mapMaybe = Maybe.mapMaybe + {-# INLINE mapMaybe #-} catMaybes = Maybe.catMaybes - {-# INLINABLE catMaybes #-} + {-# INLINE catMaybes #-} filter = Prelude.filter - {-# INLINABLE filter #-} + {-# INLINE filter #-} instance Witherable IM.IntMap where - wither f = fmap IM.fromAscList . wither (\(i, a) -> fmap ((,) i) <$> f a) . IM.toList - {-# INLINABLE wither #-} mapMaybe = IM.mapMaybe {-# INLINE mapMaybe #-} filter = IM.filter {-# INLINE filter #-} instance Ord k => Witherable (M.Map k) where - wither f = fmap M.fromAscList . wither (\(i, a) -> fmap ((,) i) <$> f a) . M.toList - {-# INLINABLE wither #-} mapMaybe = M.mapMaybe {-# INLINE mapMaybe #-} filter = M.filter - {-# INLINABLE filter #-} + {-# INLINE filter #-} instance (Eq k, Hashable k) => Witherable (HM.HashMap k) where wither f = fmap HM.fromList . wither (\(i, a) -> fmap ((,) i) <$> f a) . HM.toList {-# INLINABLE wither #-} filter = HM.filter - {-# INLINABLE filter #-} + {-# INLINE filter #-} #if (MIN_VERSION_base(4,7,0)) instance Witherable Proxy where @@ -145,10 +145,25 @@ wither f = fmap V.fromList . wither f . V.toList {-# INLINABLE wither #-} filter = V.filter - {-# INLINABLE filter #-} + {-# INLINE filter #-} instance Witherable S.Seq where wither f = fmap S.fromList . wither f . F.toList {-# INLINABLE wither #-} filter = S.filter - {-# INLINABLE filter #-} + {-# INLINE filter #-} + +-- | Traversable containers which hold 'Maybe' are witherable. +newtype Chipped t a = Chipped { getChipped :: t (Maybe a) } deriving (Functor, F.Foldable, T.Traversable) + +deriving instance Show (t (Maybe a)) => Show (Chipped t a) +deriving instance Read (t (Maybe a)) => Read (Chipped t a) +deriving instance Eq (t (Maybe a)) => Eq (Chipped t a) +deriving instance Ord (t (Maybe a)) => Ord (Chipped t a) + +instance Applicative t => Applicative (Chipped t) where + pure a = Chipped (pure (pure a)) + Chipped f <*> Chipped t = Chipped (liftA2 (<*>) f t) + +instance T.Traversable t => Witherable (Chipped t) where + wither f = fmap Chipped . T.traverse (wither f) . getChipped
witherable.cabal view
@@ -1,5 +1,5 @@ name: witherable -version: 0.1.2.1 +version: 0.1.2.2 synopsis: Generalization of filter and catMaybes -- description: homepage: https://github.com/fumieval/witherable