Hello community, here is the log from the commit of package ghc-witherable for openSUSE:Factory checked in at 2017-04-14 13:39:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-witherable (Old) and /work/SRC/openSUSE:Factory/.ghc-witherable.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-witherable" Fri Apr 14 13:39:14 2017 rev:2 rq:485175 version:0.1.3.4 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-witherable/ghc-witherable.changes 2017-01-18 21:41:09.034151045 +0100 +++ /work/SRC/openSUSE:Factory/.ghc-witherable.new/ghc-witherable.changes 2017-04-14 13:39:15.614339466 +0200 @@ -1,0 +2,5 @@ +Mon Mar 27 12:37:47 UTC 2017 - [email protected] + +- Update to version 0.1.3.4 with cabal2obs. + +------------------------------------------------------------------- Old: ---- witherable-0.1.3.3.tar.gz New: ---- witherable-0.1.3.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-witherable.spec ++++++ --- /var/tmp/diff_new_pack.hzZxCO/_old 2017-04-14 13:39:16.786173849 +0200 +++ /var/tmp/diff_new_pack.hzZxCO/_new 2017-04-14 13:39:16.790173285 +0200 @@ -1,7 +1,7 @@ # # spec file for package ghc-witherable # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,15 +18,14 @@ %global pkg_name witherable Name: ghc-%{pkg_name} -Version: 0.1.3.3 +Version: 0.1.3.4 Release: 0 -Summary: Generalization of filter and catMaybes +Summary: Filterable traversable License: BSD-3-Clause -Group: System/Libraries +Group: Development/Languages/Other Url: https://hackage.haskell.org/package/%{pkg_name} Source0: https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz BuildRequires: ghc-Cabal-devel -# Begin cabal-rpm deps: BuildRequires: ghc-base-orphans-devel BuildRequires: ghc-containers-devel BuildRequires: ghc-hashable-devel @@ -35,10 +34,10 @@ BuildRequires: ghc-unordered-containers-devel BuildRequires: ghc-vector-devel BuildRoot: %{_tmppath}/%{name}-%{version}-build -# End cabal-rpm deps %description -Generalization of filter and catMaybes. +A stronger variant of `traverse` which can remove elements and generalised +mapMaybe, catMaybes, filter. %package devel Summary: Haskell %{pkg_name} library development files @@ -54,15 +53,12 @@ %prep %setup -q -n %{pkg_name}-%{version} - %build %ghc_lib_build - %install %ghc_lib_install - %post devel %ghc_pkg_recache ++++++ witherable-0.1.3.3.tar.gz -> witherable-0.1.3.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/witherable-0.1.3.3/LICENSE new/witherable-0.1.3.4/LICENSE --- old/witherable-0.1.3.3/LICENSE 2014-12-05 06:45:39.000000000 +0100 +++ new/witherable-0.1.3.4/LICENSE 2017-03-15 08:21:43.000000000 +0100 @@ -1,30 +1,30 @@ -Copyright (c) 2014, Fumiaki Kinoshita - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of Fumiaki Kinoshita nor the names of other - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Copyright (c) 2014, Fumiaki Kinoshita + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Fumiaki Kinoshita nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/witherable-0.1.3.3/Setup.hs new/witherable-0.1.3.4/Setup.hs --- old/witherable-0.1.3.3/Setup.hs 2014-12-05 06:45:39.000000000 +0100 +++ new/witherable-0.1.3.4/Setup.hs 2017-03-15 08:21:43.000000000 +0100 @@ -1,2 +1,2 @@ -import Distribution.Simple -main = defaultMain +import Distribution.Simple +main = defaultMain diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/witherable-0.1.3.3/src/Data/Witherable.hs new/witherable-0.1.3.4/src/Data/Witherable.hs --- old/witherable-0.1.3.3/src/Data/Witherable.hs 2016-02-29 22:54:17.000000000 +0100 +++ new/witherable-0.1.3.4/src/Data/Witherable.hs 2017-03-15 08:34:42.000000000 +0100 @@ -1,265 +1,289 @@ -{-# LANGUAGE Rank2Types #-} -{-# LANGUAGE CPP, DeriveFunctor, DeriveFoldable, DeriveTraversable, StandaloneDeriving, UndecidableInstances, FlexibleContexts #-} -#if __GLASGOW_HASKELL__ >= 702 -{-# LANGUAGE Trustworthy #-} -#endif ------------------------------------------------------------------------------ --- | --- Module : Data.Witherable --- Copyright : (c) Fumiaki Kinoshita 2015 --- License : BSD3 --- --- Maintainer : Fumiaki Kinoshita <[email protected]> --- Stability : provisional --- Portability : non-portable --- ------------------------------------------------------------------------------ -module Data.Witherable (Witherable(..) - , witherM - , blightM - , ordNub - , hashNub - , forMaybe - -- * Generalization - , FilterLike, Filter, FilterLike', Filter' - , witherOf - , forMaybeOf - , mapMaybeOf - , catMaybesOf - , filterAOf - , filterOf - , ordNubOf - , hashNubOf - -- * Cloning - , cloneFilter - , Peat(..) - -- * Witherable from Traversable - , Chipped(..) - ) - -where -import qualified Data.Maybe as Maybe -import qualified Data.IntMap.Lazy as IM -import qualified Data.Map.Lazy as M -import qualified Data.Sequence as S -import qualified Data.Vector as V -import qualified Data.HashMap.Strict as HM -import qualified Data.Set as Set -import qualified Data.HashSet as HSet -import Control.Applicative -import qualified Data.Traversable as T -import qualified Data.Foldable as F -import Data.Hashable -import Data.Functor.Identity -import Control.Monad.Trans.Maybe -import Control.Monad.Trans.State.Strict -import Data.Monoid -import Data.Orphans () -#if (MIN_VERSION_base(4,7,0)) -import Data.Proxy -#endif -import Prelude -- Fix redundant import warning - -type FilterLike f s t a b = (a -> f (Maybe b)) -> s -> f t -type Filter s t a b = forall f. Applicative f => FilterLike f s t a b -type FilterLike' f s a = FilterLike f s s a a -type Filter' s a = forall f. Applicative f => FilterLike' f s a - -newtype Peat a b t = Peat { runPeat :: forall f. Applicative f => (a -> f (Maybe b)) -> f t } - -instance Functor (Peat a b) where - fmap f (Peat k) = Peat (fmap f . k) - {-# INLINE fmap #-} - -instance Applicative (Peat a b) where - pure a = Peat $ const (pure a) - {-# INLINE pure #-} - Peat f <*> Peat g = Peat $ \h -> f h <*> g h - {-# INLINE (<*>) #-} - -cloneFilter :: FilterLike (Peat a b) s t a b -> Filter s t a b -cloneFilter l f = (`runPeat` f) . l (\a -> Peat $ \g -> g a) -{-# INLINABLE cloneFilter #-} - --- | 'witherOf' is actually 'id', but left for consistency. -witherOf :: FilterLike f s t a b -> (a -> f (Maybe b)) -> s -> f t -witherOf = id -{-# INLINE witherOf #-} - --- | @'forMaybeOf' == 'flip'@ -forMaybeOf :: FilterLike f s t a b -> s -> (a -> f (Maybe b)) -> f t -forMaybeOf = flip -{-# INLINE forMaybeOf #-} - --- | 'mapMaybe' through a filter. -mapMaybeOf :: FilterLike Identity s t a b -> (a -> Maybe b) -> s -> t -mapMaybeOf w f = runIdentity . w (Identity . f) -{-# INLINE mapMaybeOf #-} - --- | 'catMaybes' through a filter. -catMaybesOf :: FilterLike Identity s t (Maybe a) a -> s -> t -catMaybesOf w = mapMaybeOf w id -{-# INLINE catMaybesOf #-} - -filterAOf :: Functor f => FilterLike' f s a -> (a -> f Bool) -> s -> f s -filterAOf w f = w $ \a -> (\b -> if b then Just a else Nothing) <$> f a -{-# INLINABLE filterAOf #-} - --- | Filter each element of a structure targeted by a 'Filter'. -filterOf :: FilterLike' Identity s a -> (a -> Bool) -> s -> s -filterOf w f = runIdentity . filterAOf w (Identity . f) -{-# INLINE filterOf #-} - --- | Like `traverse`, but you can remove elements instead of updating them. --- --- @'traverse' f ≡ 'wither' ('fmap' 'Just' . f)@ --- --- A definition of 'wither' must satisfy the following laws: --- --- [/identity/] --- @'wither' ('pure' . Just) ≡ 'pure'@ --- --- [/composition/] --- @'Data.Functor.Compose.Compose' . 'fmap' ('wither' f) . 'wither' g ≡ 'wither' ('Data.Functor.Compose.Compose' . 'fmap' ('wither' f) . g)@ --- --- Parametricity implies the naturality law: --- --- @t . 'wither' f = 'wither' (t . f)@ --- - -class T.Traversable t => Witherable t where - - wither :: Applicative f => (a -> f (Maybe b)) -> t a -> f (t b) - wither f = fmap catMaybes . T.traverse f - {-# INLINE wither #-} - - mapMaybe :: (a -> Maybe b) -> t a -> t b - mapMaybe = mapMaybeOf wither - {-# INLINE mapMaybe #-} - - catMaybes :: t (Maybe a) -> t a - catMaybes = mapMaybe id - {-# INLINE catMaybes #-} - - filterA :: Applicative f => (a -> f Bool) -> t a -> f (t a) - filterA = filterAOf wither - - filter :: (a -> Bool) -> t a -> t a - filter = filterOf wither - {-# INLINE filter #-} -#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707 - {-# MINIMAL wither | mapMaybe | catMaybes #-} -#endif - --- | @'forMaybe' == 'flip' 'wither'@ -forMaybe :: (Witherable t, Applicative f) => t a -> (a -> f (Maybe b)) -> f (t b) -forMaybe = flip wither -{-# INLINE forMaybe #-} - -witherM :: (Witherable t, Monad m) => (a -> MaybeT m b) -> t a -> m (t b) -witherM f = unwrapMonad . wither (WrapMonad . runMaybeT . f) -{-# INLINE witherM #-} - --- | 'blightM' is 'witherM' with its arguments flipped. -blightM :: (Monad m, Witherable t) => t a -> (a -> MaybeT m b) -> m (t b) -blightM = flip witherM -{-# INLINE blightM #-} - --- | Remove the duplicate elements through a filter. -ordNubOf :: Ord a => FilterLike' (State (Set.Set a)) s a -> s -> s -ordNubOf w t = evalState (w f t) Set.empty - where - f a = state $ \s -> if Set.member a s - then (Nothing, s) - else (Just a, Set.insert a s) -{-# INLINE ordNubOf #-} - --- | Remove the duplicate elements through a filter. --- It is often faster than 'ordNubOf', especially when the comparison is expensive. -hashNubOf :: (Eq a, Hashable a) => FilterLike' (State (HSet.HashSet a)) s a -> s -> s -hashNubOf w t = evalState (w f t) HSet.empty - where - f a = state $ \s -> if HSet.member a s - then (Nothing, s) - else (Just a, HSet.insert a s) -{-# INLINE hashNubOf #-} - --- | Removes duplicate elements from a list, keeping only the first --- occurrence. This is exponentially quicker than using --- 'Data.List.nub' from "Data.List". -ordNub :: (Witherable t, Ord a) => t a -> t a -ordNub = ordNubOf wither -{-# INLINE ordNub #-} - --- | Removes duplicate elements from a list, keeping only the first --- occurrence. This is usually faster than 'ordNub', especially for --- things that have a slow comparion (like 'String'). -hashNub :: (Witherable t, Eq a, Hashable a) => t a -> t a -hashNub = hashNubOf wither -{-# INLINE hashNub #-} - -instance Witherable Maybe where - wither _ Nothing = pure Nothing - wither f (Just a) = f a - {-# INLINABLE wither #-} - -instance Monoid e => Witherable (Either e) where - wither _ (Left e) = pure (Left e) - wither f (Right a) = fmap (maybe (Left mempty) Right) (f a) - {-# INLINABLE wither #-} - -instance Witherable [] where - wither f = go where - go (x:xs) = maybe id (:) <$> f x <*> go xs - go [] = pure [] - {-# INLINE[0] wither #-} - mapMaybe = Maybe.mapMaybe - catMaybes = Maybe.catMaybes - filter = Prelude.filter - -instance Witherable IM.IntMap where - mapMaybe = IM.mapMaybe - filter = IM.filter - -instance Ord k => Witherable (M.Map k) where - mapMaybe = M.mapMaybe - filter = M.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 - -#if (MIN_VERSION_base(4,7,0)) -instance Witherable Proxy where - wither _ Proxy = pure Proxy -#endif - -instance Witherable (Const r) where - wither _ (Const r) = pure (Const r) - {-# INLINABLE wither #-} - -instance Witherable V.Vector where - wither f = fmap V.fromList . wither f . V.toList - {-# INLINABLE wither #-} - filter = V.filter - -instance Witherable S.Seq where - wither f = fmap S.fromList . wither f . F.toList - {-# INLINABLE wither #-} - filter = S.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 +{-# LANGUAGE Rank2Types #-} +{-# LANGUAGE CPP, DeriveFunctor, DeriveFoldable, DeriveTraversable, StandaloneDeriving, UndecidableInstances, FlexibleContexts #-} +#if __GLASGOW_HASKELL__ >= 702 +{-# LANGUAGE Trustworthy #-} +#endif +----------------------------------------------------------------------------- +-- | +-- Module : Data.Witherable +-- Copyright : (c) Fumiaki Kinoshita 2015 +-- License : BSD3 +-- +-- Maintainer : Fumiaki Kinoshita <[email protected]> +-- Stability : provisional +-- Portability : non-portable +-- +----------------------------------------------------------------------------- +module Data.Witherable (Witherable(..) + , witherM + , blightM + , ordNub + , hashNub + , forMaybe + -- * Generalization + , FilterLike, Filter, FilterLike', Filter' + , witherOf + , forMaybeOf + , mapMaybeOf + , catMaybesOf + , filterAOf + , filterOf + , ordNubOf + , hashNubOf + -- * Cloning + , cloneFilter + , Peat(..) + -- * Witherable from Traversable + , Chipped(..) + ) + +where +import qualified Data.Maybe as Maybe +import qualified Data.IntMap.Lazy as IM +import qualified Data.Map.Lazy as M +import qualified Data.Sequence as S +import qualified Data.Vector as V +import qualified Data.HashMap.Strict as HM +import qualified Data.Set as Set +import qualified Data.HashSet as HSet +import Control.Applicative +import qualified Data.Traversable as T +import qualified Data.Foldable as F +import Data.Functor.Compose +import Data.Hashable +import Data.Functor.Identity +import Control.Monad.Trans.Maybe +import Control.Monad.Trans.State.Strict +import Data.Monoid +import Data.Orphans () +#if (MIN_VERSION_base(4,7,0)) +import Data.Proxy +#endif +import Prelude -- Fix redundant import warning + +-- | This type allows combinators to take a 'Filter' specializing the parameter @f@. +type FilterLike f s t a b = (a -> f (Maybe b)) -> s -> f t + +-- | A 'Filter' is like a <http://hackage.haskell.org/package/lens-4.13.2.1/docs/Control-Lens-Type.html#t:Traversal Traversal>, +-- but you can also remove targets. +type Filter s t a b = forall f. Applicative f => FilterLike f s t a b + +-- | A simple 'FilterLike'. +type FilterLike' f s a = FilterLike f s s a a + +-- | A simple 'Filter'. +type Filter' s a = forall f. Applicative f => FilterLike' f s a + +-- | This is used to characterize and clone a 'Filter'. +-- Since @FilterLike (Peat a b) s t a b@ is monomorphic, it can be used to store a filter in a container. +newtype Peat a b t = Peat { runPeat :: forall f. Applicative f => (a -> f (Maybe b)) -> f t } + +instance Functor (Peat a b) where + fmap f (Peat k) = Peat (fmap f . k) + {-# INLINE fmap #-} + +instance Applicative (Peat a b) where + pure a = Peat $ const (pure a) + {-# INLINE pure #-} + Peat f <*> Peat g = Peat $ \h -> f h <*> g h + {-# INLINE (<*>) #-} + +-- | Reconstitute a 'Filter' from its monomorphic form. +cloneFilter :: FilterLike (Peat a b) s t a b -> Filter s t a b +cloneFilter l f = (`runPeat` f) . l (\a -> Peat $ \g -> g a) +{-# INLINABLE cloneFilter #-} + +-- | 'witherOf' is actually 'id', but left for consistency. +witherOf :: FilterLike f s t a b -> (a -> f (Maybe b)) -> s -> f t +witherOf = id +{-# INLINE witherOf #-} + +-- | @'forMaybeOf' == 'flip'@ +forMaybeOf :: FilterLike f s t a b -> s -> (a -> f (Maybe b)) -> f t +forMaybeOf = flip +{-# INLINE forMaybeOf #-} + +-- | 'mapMaybe' through a filter. +mapMaybeOf :: FilterLike Identity s t a b -> (a -> Maybe b) -> s -> t +mapMaybeOf w f = runIdentity . w (Identity . f) +{-# INLINE mapMaybeOf #-} + +-- | 'catMaybes' through a filter. +catMaybesOf :: FilterLike Identity s t (Maybe a) a -> s -> t +catMaybesOf w = mapMaybeOf w id +{-# INLINE catMaybesOf #-} + +-- | 'filterA' through a filter. +filterAOf :: Functor f => FilterLike' f s a -> (a -> f Bool) -> s -> f s +filterAOf w f = w $ \a -> (\b -> if b then Just a else Nothing) <$> f a +{-# INLINABLE filterAOf #-} + +-- | Filter each element of a structure targeted by a 'Filter'. +filterOf :: FilterLike' Identity s a -> (a -> Bool) -> s -> s +filterOf w f = runIdentity . filterAOf w (Identity . f) +{-# INLINE filterOf #-} + +-- | Like 'Traversable', but you can remove elements instead of updating them. +-- +-- A definition of 'wither' must satisfy the following laws: +-- +-- [/identity/] +-- @'wither' ('pure' . Just) ≡ 'pure'@ +-- +-- [/composition/] +-- @'Compose' . 'fmap' ('wither' f) . 'wither' g ≡ 'wither' ('Compose' . 'fmap' ('wither' f) . g)@ +-- +-- Parametricity implies the naturality law: +-- +-- @t . 'wither' f ≡ 'wither' (t . f)@ +-- + +class T.Traversable t => Witherable t where + + -- | @'traverse' f ≡ 'wither' ('fmap' 'Just' . f)@ + wither :: Applicative f => (a -> f (Maybe b)) -> t a -> f (t b) + wither f = fmap catMaybes . T.traverse f + {-# INLINE wither #-} + + -- | @'mapMaybe' f . 'mapMaybe' g ≡ 'mapMaybe' (f <=< g)@ + mapMaybe :: (a -> Maybe b) -> t a -> t b + mapMaybe = mapMaybeOf wither + {-# INLINE mapMaybe #-} + + -- | @'catMaybes' ≡ 'mapMaybe' 'id'@ + catMaybes :: t (Maybe a) -> t a + catMaybes = mapMaybe id + {-# INLINE catMaybes #-} + + -- | @'Compose' . 'fmap' ('filterA' f) . 'filterA' g ≡ 'filterA' (\x -> 'Compose' $ 'fmap' (\b -> (b&&) <$> f x) (g x)@ + filterA :: Applicative f => (a -> f Bool) -> t a -> f (t a) + filterA = filterAOf wither + + -- | @'filter' f . 'filter' g ≡ filter ('liftA2' ('&&') f g)@ + filter :: (a -> Bool) -> t a -> t a + filter = filterOf wither + {-# INLINE filter #-} +#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707 + {-# MINIMAL wither | mapMaybe | catMaybes #-} +#endif + +-- | @'forMaybe' = 'flip' 'wither'@ +forMaybe :: (Witherable t, Applicative f) => t a -> (a -> f (Maybe b)) -> f (t b) +forMaybe = flip wither +{-# INLINE forMaybe #-} + +-- | A variant of `wither` that works on 'MaybeT'. +witherM :: (Witherable t, Monad m) => (a -> MaybeT m b) -> t a -> m (t b) +witherM f = unwrapMonad . wither (WrapMonad . runMaybeT . f) +{-# INLINE witherM #-} + +-- | 'blightM' is 'witherM' with its arguments flipped. +blightM :: (Monad m, Witherable t) => t a -> (a -> MaybeT m b) -> m (t b) +blightM = flip witherM +{-# INLINE blightM #-} + +-- | Remove the duplicate elements through a filter. +ordNubOf :: Ord a => FilterLike' (State (Set.Set a)) s a -> s -> s +ordNubOf w t = evalState (w f t) Set.empty + where + f a = state $ \s -> if Set.member a s + then (Nothing, s) + else (Just a, Set.insert a s) +{-# INLINE ordNubOf #-} + +-- | Remove the duplicate elements through a filter. +-- It is often faster than 'ordNubOf', especially when the comparison is expensive. +hashNubOf :: (Eq a, Hashable a) => FilterLike' (State (HSet.HashSet a)) s a -> s -> s +hashNubOf w t = evalState (w f t) HSet.empty + where + f a = state $ \s -> if HSet.member a s + then (Nothing, s) + else (Just a, HSet.insert a s) +{-# INLINE hashNubOf #-} + +-- | Removes duplicate elements from a list, keeping only the first +-- occurrence. This is asymptotically faster than using +-- 'Data.List.nub' from "Data.List". +ordNub :: (Witherable t, Ord a) => t a -> t a +ordNub = ordNubOf wither +{-# INLINE ordNub #-} + +-- | Removes duplicate elements from a list, keeping only the first +-- occurrence. This is usually faster than 'ordNub', especially for +-- things that have a slow comparion (like 'String'). +hashNub :: (Witherable t, Eq a, Hashable a) => t a -> t a +hashNub = hashNubOf wither +{-# INLINE hashNub #-} + +instance Witherable Maybe where + wither _ Nothing = pure Nothing + wither f (Just a) = f a + {-# INLINABLE wither #-} + +instance Monoid e => Witherable (Either e) where + wither _ (Left e) = pure (Left e) + wither f (Right a) = fmap (maybe (Left mempty) Right) (f a) + {-# INLINABLE wither #-} + +instance Witherable [] where + wither f = go where + go (x:xs) = maybe id (:) <$> f x <*> go xs + go [] = pure [] + {-# INLINE[0] wither #-} + mapMaybe = Maybe.mapMaybe + catMaybes = Maybe.catMaybes + filter = Prelude.filter + +instance Witherable IM.IntMap where + mapMaybe = IM.mapMaybe + filter = IM.filter + +instance Witherable (M.Map k) where + mapMaybe = M.mapMaybe + filter = M.filter + +instance (Eq k, Hashable k) => Witherable (HM.HashMap k) where + mapMaybe = HM.mapMaybe + filter = HM.filter + +#if (MIN_VERSION_base(4,7,0)) +instance Witherable Proxy where + wither _ Proxy = pure Proxy +#endif + +instance Witherable (Const r) where + wither _ (Const r) = pure (Const r) + {-# INLINABLE wither #-} + +instance Witherable V.Vector where + wither f = fmap V.fromList . wither f . V.toList + {-# INLINABLE wither #-} + filter = V.filter + +instance Witherable S.Seq where + wither f = fmap S.fromList . wither f . F.toList + {-# INLINABLE wither #-} + filter = S.filter + +instance (T.Traversable f, Witherable g) => Witherable (Compose f g) where + wither f = fmap Compose . T.traverse (wither f) . getCompose + +-- | Traversable containers which hold 'Maybe' are witherable. +newtype Chipped t a = Chipped { getChipped :: t (Maybe a) } deriving (Functor, F.Foldable, T.Traversable) + +{-# DEPRECATED Chipped "Use 'Compose t Maybe' instead " #-} + +instance (T.Traversable t) => Witherable (MaybeT t) where + wither f = fmap MaybeT . T.traverse (wither f) . runMaybeT + +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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/witherable-0.1.3.3/witherable.cabal new/witherable-0.1.3.4/witherable.cabal --- old/witherable-0.1.3.3/witherable.cabal 2016-02-29 22:51:17.000000000 +0100 +++ new/witherable-0.1.3.4/witherable.cabal 2017-03-15 08:57:32.000000000 +0100 @@ -1,29 +1,34 @@ -name: witherable -version: 0.1.3.3 -synopsis: Generalization of filter and catMaybes --- description: -homepage: https://github.com/fumieval/witherable -license: BSD3 -license-file: LICENSE -author: Fumiaki Kinoshita -maintainer: Fumiaki Kinoshita <[email protected]> -copyright: Copyright (c) 2014 Fumiaki Kinoshita -category: Data -build-type: Simple --- extra-source-files: -cabal-version: >=1.10 - -library - exposed-modules: Data.Witherable - -- other-modules: - -- other-extensions: - build-depends: base == 4.*, - base-orphans, - containers, - hashable, - transformers, - unordered-containers, - vector - hs-source-dirs: src - ghc-options: -Wall - default-language: Haskell2010 +name: witherable +version: 0.1.3.4 +synopsis: filterable traversable +description: A stronger variant of `traverse` which can remove elements and generalised mapMaybe, catMaybes, filter +homepage: https://github.com/fumieval/witherable +license: BSD3 +license-file: LICENSE +author: Fumiaki Kinoshita +maintainer: Fumiaki Kinoshita <[email protected]> +copyright: Copyright (c) 2014 Fumiaki Kinoshita +category: Data +build-type: Simple +-- extra-source-files: +cabal-version: >=1.10 +tested-With: GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2 + +source-repository head + type: git + location: https://github.com/fumieval/witherable.git + +library + exposed-modules: Data.Witherable + -- other-modules: + -- other-extensions: + build-depends: base == 4.*, + base-orphans, + containers, + hashable, + transformers, + unordered-containers, + vector + hs-source-dirs: src + ghc-options: -Wall + default-language: Haskell2010
