packages feed

bifunctors 4.1.1 → 4.1.1.1

raw patch · 4 files changed

+218/−2 lines, 4 files

Files

.travis.yml view
@@ -1,4 +1,5 @@-language: haskell+# See https://github.com/hvr/multi-ghc-travis for more information+ notifications:   irc:     channels:@@ -6,3 +7,46 @@     skip_join: true     template:       - "\x0313bifunctors\x03/\x0306%{branch}\x03 \x0314%{commit}\x03 %{build_url} %{message}"++env:+ # - GHCVER=7.0.1+ # - GHCVER=7.0.2+ # - GHCVER=7.0.3+ # - GHCVER=7.0.4+ # - GHCVER=7.2.1+ # - GHCVER=7.2.2+ - GHCVER=7.4.1+ - GHCVER=7.4.2+ - GHCVER=7.6.1+ - GHCVER=7.6.2+ - GHCVER=7.6.3+ - GHCVER=head++matrix:+  allow_failures:+   - env: GHCVER=head++before_install:+ - sudo add-apt-repository -y ppa:hvr/ghc+ - sudo apt-get update+ - sudo apt-get install cabal-install-1.18 ghc-$GHCVER+ - export PATH=/opt/ghc/$GHCVER/bin:$PATH++install:+ - cabal-1.18 update+ - cabal-1.18 install --only-dependencies --enable-tests++script:+ - cabal-1.18 configure --enable-tests -v2+ - cabal-1.18 build+ - cabal-1.18 test+ - cabal-1.18 check+ - cabal-1.18 sdist+ - export SRC_TGZ=$(cabal-1.18 info . | awk '{print $2 ".tar.gz";exit}') ;+   cd dist/;+   if [ -f "$SRC_TGZ" ]; then+      cabal-1.18 install "$SRC_TGZ";+   else+      echo "expected '$SRC_TGZ' not found";+      exit 1;+   fi
bifunctors.cabal view
@@ -1,6 +1,6 @@ name:          bifunctors category:      Data, Functors-version:       4.1.1+version:       4.1.1.1 license:       BSD3 cabal-version: >= 1.6 license-file:  LICENSE
src/Data/Bifoldable.hs view
@@ -32,19 +32,56 @@ import Data.Monoid import Data.Tagged +-- | Minimal definition either 'bifoldr' or 'bifoldMap'++-- | 'Bifoldable' identifies foldable structures with two different varieties of+-- elements. Common examples are 'Either' and '(,)':+--+-- > instance Bifoldable Either where+-- >   bifoldMap f _ (Left  a) = f a+-- >   bifoldMap _ g (Right b) = g b+-- >+-- > instance Bifoldable (,) where+-- >   bifoldr f g z (a, b) = f a (g b z)+--+-- When defining more than the minimal set of definitions, one should ensure+-- that the following identities hold:+--+-- @+-- 'bifold' ≡ 'bifoldMap' 'id' 'id'+-- 'bifoldMap' f g ≡ 'bifoldr' ('mappend' . f) ('mappend' . g) 'mempty'+-- 'bifoldr' f g z t ≡ 'appEndo' ('bifoldMap' (Endo . f) (Endo . g) t) z+-- @ class Bifoldable p where+  -- | Combines the elements of a structure using a monoid.+  --+  -- @'bifold' ≡ 'bifoldMap' 'id' 'id'@   bifold :: Monoid m => p m m -> m   bifold = bifoldMap id id   {-# INLINE bifold #-} +  -- | Combines the elements of a structure, given ways of mapping them to a+  -- common monoid.+  --+  -- @'bifoldMap' f g ≡ 'bifoldr' ('mappend' . f) ('mappend' . g) 'mempty'@   bifoldMap :: Monoid m => (a -> m) -> (b -> m) -> p a b -> m   bifoldMap f g = bifoldr (mappend . f) (mappend . g) mempty   {-# INLINE bifoldMap #-} +  -- | Combines the elements of a structure in a right associative manner. Given+  -- a hypothetical function @toEitherList :: p a b -> [Either a b]@ yielding a+  -- list of all elements of a structure in order, the following would hold:+  --+  -- @'bifoldr' f g z ≡ 'foldr' ('either' f g) z . toEitherList@   bifoldr :: (a -> c -> c) -> (b -> c -> c) -> c -> p a b -> c   bifoldr f g z t = appEndo (bifoldMap (Endo . f) (Endo . g) t) z   {-# INLINE bifoldr #-} +  -- | Combines the elments of a structure in a left associative manner. Given a+  -- hypothetical function @toEitherList :: p a b -> [Either a b]@ yielding a+  -- list of all elements of a structure in order, the following would hold:+  --+  -- @'bifoldl' f g z ≡ 'foldl' (\acc -> 'either' (f acc) (g acc)) z .  toEitherList@   bifoldl :: (c -> a -> c) -> (c -> b -> c) -> c -> p a b -> c   bifoldl f g z t = appEndo (getDual (bifoldMap (Dual . Endo . flip f) (Dual . Endo . flip g) t)) z   {-# INLINE bifoldl #-}@@ -78,70 +115,93 @@   bifoldMap _ g (Right b) = g b   {-# INLINE bifoldMap #-} +-- | As 'bifoldr', but strict in the result of the reduction functions at each+-- step. bifoldr' :: Bifoldable t => (a -> c -> c) -> (b -> c -> c) -> c -> t a b -> c bifoldr' f g z0 xs = bifoldl f' g' id xs z0 where   f' k x z = k $! f x z   g' k x z = k $! g x z {-# INLINE bifoldr' #-} +-- | Right associative monadic bifold over a structure. bifoldrM :: (Bifoldable t, Monad m) => (a -> c -> m c) -> (b -> c -> m c) -> c -> t a b -> m c bifoldrM f g z0 xs = bifoldl f' g' return xs z0 where   f' k x z = f x z >>= k   g' k x z = g x z >>= k {-# INLINE bifoldrM #-} +-- | As 'bifoldl', but strict in the result of the reductionf unctions at each+-- step. bifoldl':: Bifoldable t => (a -> b -> a) -> (a -> c -> a) -> a -> t b c -> a bifoldl' f g z0 xs = bifoldr f' g' id xs z0 where   f' x k z = k $! f z x   g' x k z = k $! g z x {-# INLINE bifoldl' #-} +-- | Left associative monadic bifold over a structure. bifoldlM :: (Bifoldable t, Monad m) => (a -> b -> m a) -> (a -> c -> m a) -> a -> t b c -> m a bifoldlM f g z0 xs = bifoldr f' g' return xs z0 where   f' x k z = f z x >>= k   g' x k z = g z x >>= k {-# INLINE bifoldlM #-} +-- | As 'Data.Bitraversable.bitraverse', but ignores the results of the+-- functions, merely performing the "actions". bitraverse_ :: (Bifoldable t, Applicative f) => (a -> f c) -> (b -> f d) -> t a b -> f () bitraverse_ f g = bifoldr ((*>) . f) ((*>) . g) (pure ()) {-# INLINE bitraverse_ #-} +-- | As 'bitraverse_', but with the structure as the primary argument. bifor_ :: (Bifoldable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f () bifor_ t f g = bitraverse_ f g t {-# INLINE bifor_ #-} +-- | As 'Data.Bitraversable.bimapM', but ignores the results of the functions,+-- merely performing+-- the "actions". bimapM_:: (Bifoldable t, Monad m) => (a -> m c) -> (b -> m d) -> t a b -> m () bimapM_ f g = bifoldr ((>>) . f) ((>>) . g) (return ()) {-# INLINE bimapM_ #-} +-- | As 'bimapM_', but with the structure as the primary argument. biforM_ :: (Bifoldable t, Monad m) => t a b ->  (a -> m c) -> (b -> m d) -> m () biforM_ t f g = bimapM_ f g t {-# INLINE biforM_ #-} +-- | As 'Data.Bitraversable.bisequenceA', but ignores the results of the actions. bisequenceA_ :: (Bifoldable t, Applicative f) => t (f a) (f b) -> f () bisequenceA_ = bifoldr (*>) (*>) (pure ()) {-# INLINE bisequenceA_ #-} +-- | As 'Data.Bitraversable.bisequence', but ignores the results of the actions. bisequence_ :: (Bifoldable t, Monad m) => t (m a) (m b) -> m () bisequence_ = bifoldr (>>) (>>) (return ()) {-# INLINE bisequence_ #-} +-- | Collects the list of elements of a structure in order. biList :: Bifoldable t => t a a -> [a] biList = bifoldr (:) (:) [] {-# INLINE biList #-} +-- | Reduces a structure of lists to the concatenation of those lists. biconcat :: Bifoldable t => t [a] [a] -> [a] biconcat = bifold {-# INLINE biconcat #-} +-- | Given a means of mapping the elements of a structure to lists, computes the+-- concatenation of all such lists in order. biconcatMap :: Bifoldable t => (a -> [c]) -> (b -> [c]) -> t a b -> [c] biconcatMap = bifoldMap {-# INLINE biconcatMap #-} +-- | Determines whether any element of the structure satisfies the appropriate+-- predicate. biany :: Bifoldable t => (a -> Bool) -> (b -> Bool) -> t a b -> Bool biany p q = getAny . bifoldMap (Any . p) (Any . q) {-# INLINE biany #-} +-- | Determines whether all elements of the structure satisfy the appropriate+-- predicate. biall :: Bifoldable t => (a -> Bool) -> (b -> Bool) -> t a b -> Bool biall p q = getAll . bifoldMap (All . p) (All . q) {-# INLINE biall #-}
src/Data/Bitraversable.hs view
@@ -25,19 +25,123 @@ import Data.Monoid import Data.Tagged +-- | Minimal complete definition either 'bitraverse' or 'bisequenceA'.++-- | 'Bitraversable' identifies bifunctorial data structures whose elements can+-- be traversed in order, performing 'Applicative' or 'Monad' actions at each+-- element, and collecting a result structure with the same shape.+--+-- A definition of 'traverse' must satisfy the following laws:+--+-- [/naturality/]+--   @'bitraverse' (t . f) (t . g) ≡ t . 'bitraverse' f g@+--   for every applicative transformation @t@+--+-- [/identity/]+--   @'bitraverse' 'Identity' 'Identity' ≡ 'Identity'@+--+-- [/composition/]+--   @'Compose' . 'fmap' ('bitraverse' g1 g2) . 'bitraverse' f1 f2+--     ≡ 'traverse' ('Compose' . 'fmap' g1 . f1) ('Compose' . 'fmap' g2 . f2)@+--+-- A definition of 'bisequenceA' must satisfy the following laws:+--+-- [/naturality/]+--   @'bisequenceA' . 'bimap' t t ≡ t . 'bisequenceA'@+--   for every applicative transformation @t@+--+-- [/identity/]+--   @'bisequenceA' . 'bimap' 'Identity' 'Identity' ≡ 'Identity'@+--+-- [/composition/]+--   @'bisequenceA' . 'bimap' 'Compose' 'Compose'+--     ≡ 'Compose' . 'fmap' 'bisequenceA' . 'bisequenceA'@+--+-- where an /applicative transformation/ is a function+--+-- @t :: ('Applicative' f, 'Applicative' g) => f a -> g a@+--+-- preserving the 'Applicative' operations:+--+-- @+-- t ('pure' x) = 'pure' x+-- t (f '<*>' x) = t f '<*>' t x+-- @+--+-- and the identity functor 'Identity' and composition functors 'Compose' are+-- defined as+--+-- > newtype Identity a = Identity { runIdentity :: a }+-- >+-- > instance Functor Identity where+-- >   fmap f (Identity x) = Identity (f x)+-- >+-- > instance Applicative Identity where+-- >   pure = Identity+-- >   Identity f <*> Identity x = Identity (f x)+-- >+-- > newtype Compose f g a = Compose (f (g a))+-- >+-- > instance (Functor f, Functor g) => Functor (Compose f g) where+-- >   fmap f (Compose x) = Compose (fmap (fmap f) x)+-- >+-- > instance (Applicative f, Applicative g) => Applicative (Compose f g) where+-- >   pure = Compose . pure . pure+-- >   Compose f <*> Compose x = Compose ((<*>) <$> f <*> x)+--+-- Some simple examples are 'Either' and '(,)':+--+-- > instance Bitraversable Either where+-- >   bitraverse f _ (Left x) = Left <$> f x+-- >   bitraverse _ g (Right y) = Right <$> g y+-- >+-- > instance Bitraversable (,) where+-- >   bitraverse f g (x, y) = (,) <$> f x <*> g y+--+-- 'Bitraversable' relates to its superclasses in the following ways:+--+-- @+-- 'bimap' f g ≡ 'runIdentity' . 'bitraverse' ('Identity' . f) ('Identity' . g)+-- 'bifoldMap' f g = 'getConst' . 'bitraverse' ('Const' . f) ('Const' . g)+-- @+--+-- These are available as 'bimapDefault' and 'bifoldMapDefault' respectively. class (Bifunctor t, Bifoldable t) => Bitraversable t where+  -- | Evaluates the relevant functions at each element in the structure, running+  -- the action, and builds a new structure with the same shape, using the+  -- elements produced from sequencing the actions.+  --+  -- @'bitraverse' f g ≡ 'bisequenceA' . 'bimap' f g@   bitraverse :: Applicative f => (a -> f c) -> (b -> f d) -> t a b -> f (t c d)   bitraverse f g = bisequenceA . bimap f g   {-# INLINE bitraverse #-} +  -- | Sequences all the actions in a structure, building a new structure with the+  -- same shape using the results of the actions.+  --+  -- @'bisequenceA' ≡ 'bitraverse' 'id' 'id'@   bisequenceA :: Applicative f => t (f a) (f b) -> f (t a b)   bisequenceA = bitraverse id id   {-# INLINE bisequenceA #-} +  -- | As 'bitraverse', but uses evidence that @m@ is a 'Monad' rather than an+  -- 'Applicative'.+  --+  -- @+  -- 'bimapM' f g ≡ 'bisequence' . 'bimap' f g+  -- 'bimapM' f g ≡ 'unwrapMonad' . 'bitraverse' ('WrapMonad' . f) ('WrapMonad' . g)+  -- @   bimapM :: Monad m => (a -> m c) -> (b -> m d) -> t a b -> m (t c d)   bimapM f g = unwrapMonad . bitraverse (WrapMonad . f) (WrapMonad . g)   {-# INLINE bimapM #-} +  -- | As 'bisequenceA', but uses evidence that @m@ is a 'Monad' rather than an+  -- 'Applicative'.+  --+  -- @+  -- 'bisequence' ≡ 'bimapM' 'id' 'id'+  -- 'bisequence' ≡ 'unwrapMonad' . 'bisequenceA' . 'bimap' 'WrapMonad' 'WrapMonad'+  -- @   bisequence :: Monad m => t (m a) (m b) -> m (t a b)   bisequence = bimapM id id   {-# INLINE bisequence #-}@@ -71,10 +175,12 @@   bitraverse _ g (Tagged b) = Tagged <$> g b   {-# INLINE bitraverse #-} +-- | 'bifor' is 'bitraverse' with the structure as the first argument. bifor :: (Bitraversable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f (t c d) bifor t f g = bitraverse f g t {-# INLINE bifor #-} +-- | 'biforM' is 'bimapM' with the structure as the first argument. biforM :: (Bitraversable t, Monad m) =>  t a b -> (a -> m c) -> (b -> m d) -> m (t c d) biforM t f g = bimapM f g t {-# INLINE biforM #-}@@ -96,6 +202,8 @@     in (s'', f v)   {-# INLINE (<*>) #-} +-- | Traverses a structure from left to right, threading a state of type @a@+-- and using the given actions to compute new elements for the structure. bimapAccumL :: Bitraversable t => (a -> b -> (a, c)) -> (a -> d -> (a, e)) -> a -> t b d -> (a, t c e) bimapAccumL f g s t = runStateL (bitraverse (StateL . flip f) (StateL . flip g) t) s {-# INLINE bimapAccumL #-}@@ -117,6 +225,8 @@     in (s'', f v)   {-# INLINE (<*>) #-} +-- | Traverses a structure from right to left, threading a state of type @a@+-- and using the given actions to compute new elements for the structure. bimapAccumR :: Bitraversable t => (a -> b -> (a, c)) -> (a -> d -> (a, e)) -> a -> t b d -> (a, t c e) bimapAccumR f g s t = runStateR (bitraverse (StateR . flip f) (StateR . flip g) t) s {-# INLINE bimapAccumR #-}@@ -133,10 +243,12 @@   Id f <*> Id x = Id (f x)   {-# INLINE (<*>) #-} +-- | A default definition of 'bimap' in terms of the 'Bitraversable' operations. bimapDefault :: Bitraversable t => (a -> b) -> (c -> d) -> t a c -> t b d bimapDefault f g = getId . bitraverse (Id . f) (Id . g) {-# INLINE bimapDefault #-} +-- | A default definition of 'bifoldMap' in terms of the 'Bitraversable' operations. bifoldMapDefault :: (Bitraversable t, Monoid m) => (a -> m) -> (b -> m) -> t a b -> m bifoldMapDefault f g = getConst . bitraverse (Const . f) (Const . g) {-# INLINE bifoldMapDefault #-}