distributive 0.5.0.2 → 0.5.1
raw patch · 4 files changed
+132/−25 lines, 4 filesdep +semigroupsdep ~base-orphansnew-uploaderPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: semigroups
Dependency ranges changed: base-orphans
API changes (from Hackage documentation)
+ Data.Distributive: fmapCollect :: Distributive f => (a -> b) -> f a -> f b
+ Data.Distributive: instance (Data.Distributive.Distributive a, Data.Distributive.Distributive b) => Data.Distributive.Distributive (a GHC.Generics.:*: b)
+ Data.Distributive: instance (Data.Distributive.Distributive a, Data.Distributive.Distributive b) => Data.Distributive.Distributive (a GHC.Generics.:.: b)
+ Data.Distributive: instance Data.Distributive.Distributive Data.Semigroup.First
+ Data.Distributive: instance Data.Distributive.Distributive Data.Semigroup.Last
+ Data.Distributive: instance Data.Distributive.Distributive Data.Semigroup.Max
+ Data.Distributive: instance Data.Distributive.Distributive Data.Semigroup.Min
+ Data.Distributive: instance Data.Distributive.Distributive GHC.Generics.Par1
+ Data.Distributive: instance Data.Distributive.Distributive GHC.Generics.U1
+ Data.Distributive: instance Data.Distributive.Distributive f => Data.Distributive.Distributive (GHC.Generics.M1 i c f)
+ Data.Distributive: instance Data.Distributive.Distributive f => Data.Distributive.Distributive (GHC.Generics.Rec1 f)
- Data.Distributive: comapM :: (Monad m, Distributive g) => (m a -> b) -> m (g a) -> g b
+ Data.Distributive: comapM :: (Distributive g, Monad m) => (m a -> b) -> m (g a) -> g b
- Data.Distributive: cotraverse :: (Functor f, Distributive g) => (f a -> b) -> f (g a) -> g b
+ Data.Distributive: cotraverse :: (Distributive g, Functor f) => (f a -> b) -> f (g a) -> g b
Files
- .travis.yml +27/−11
- CHANGELOG.markdown +5/−0
- distributive.cabal +13/−1
- src/Data/Distributive.hs +87/−13
.travis.yml view
@@ -14,6 +14,14 @@ matrix: include:+ - env: CABALVER=1.18 GHCVER=7.0.4 BUILD=cabal+ compiler: ": #GHC 7.0.4"+ addons: {apt: {packages: [cabal-install-1.18,ghc-7.0.4,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}++ - env: CABALVER=1.18 GHCVER=7.2.2 BUILD=cabal+ compiler: ": #GHC 7.2.2"+ addons: {apt: {packages: [cabal-install-1.18,ghc-7.2.2,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}+ - env: CABALVER=1.18 GHCVER=7.4.2 BUILD=cabal compiler: ": #GHC 7.4.2" addons: {apt: {packages: [cabal-install-1.18,ghc-7.4.2,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}@@ -32,21 +40,29 @@ # - env: BUILD=stack STACK_YAML=stack-7.8.yaml # os: osx - - env: CABALVER=1.22 GHCVER=7.10.1 BUILD=cabal- compiler: ": #GHC 7.10.1"- addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.1,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}+ - env: CABALVER=1.22 GHCVER=7.10.3 BUILD=cabal+ compiler: ": #GHC 7.10.3"+ addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}} - - env: CABALVER=1.22 GHCVER=7.10.2 BUILD=cabal- compiler: ": #GHC 7.10.2"- addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}+ - env: CABALVER=1.24 GHCVER=8.0.2 BUILD=cabal+ compiler: ": #GHC 8.0.2"+ addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.2,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}} - - env: BUILD=stack STACK_OPTIONS=--skip-ghc-check- addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}+ - env: CABALVER=1.24 GHCVER=head BUILD=cabal+ compiler: ": #GHC head"+ addons: {apt: {packages: [cabal-install-1.24,ghc-head,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}} - - env: BUILD=stack- os: osx+# - env: BUILD=stack STACK_OPTIONS=--skip-ghc-check+# addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}} +# - env: BUILD=stack+# os: osx + allow_failures:+ - env: CABALVER=1.18 GHCVER=7.0.4 BUILD=cabal+ - env: CABALVER=1.18 GHCVER=7.2.2 BUILD=cabal+ - env: CABALVER=1.24 GHCVER=head BUILD=cabal+ before_install: - unset CC - case "$BUILD" in@@ -87,7 +103,7 @@ rm -rf $HOME/.cabsnap; mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin; cabal install --only-dependencies --enable-tests --enable-benchmarks;- if [ "$GHCVER" = "7.10.1" ]; then cabal install Cabal-1.22.4.0; fi;+ if [ "$GHCVER" = "7.10.3" ]; then cabal install Cabal-1.22.4.0; fi; fi; if [ ! -d $HOME/.cabsnap ]; then echo "snapshotting package-db to build-cache";
CHANGELOG.markdown view
@@ -1,3 +1,8 @@+0.5.1+-----+* Add `Distributive` instances for datatypes from `Data.Semigroup` and `GHC.Generics`+* Add `MINIMAL` pragma for `Distributive`+ 0.5.0.2 ------- * A more elegant fix for builds on GHC 7.2
distributive.cabal view
@@ -1,6 +1,6 @@ name: distributive category: Data Structures-version: 0.5.0.2+version: 0.5.1 license: BSD3 cabal-version: >= 1.8 license-file: LICENSE@@ -25,6 +25,14 @@ type: git location: git://github.com/ekmett/distributive.git +flag semigroups+ manual: True+ default: True+ description:+ You can disable the use of the `tagged` package using `-f-tagged`.+ .+ Disabling this is an unsupported configuration, but it may be useful for accelerating builds in sandboxes for expert users.+ flag tagged manual: True default: True@@ -52,6 +60,10 @@ if impl(ghc>=7.2 && < 7.6) build-depends: ghc-prim++ if impl(ghc < 8.0)+ if flag(semigroups)+ build-depends: semigroups >= 0.11 && < 1 ghc-options: -Wall
src/Data/Distributive.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeOperators #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Distributive@@ -15,12 +16,13 @@ ( Distributive(..) , cotraverse , comapM+ , fmapCollect ) where import Control.Applicative import Control.Applicative.Backwards import Control.Monad (liftM)-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 707+#if __GLASGOW_HASKELL__ < 707 import Control.Monad.Instances () #endif import Control.Monad.Trans.Identity@@ -35,12 +37,18 @@ #if MIN_VERSION_base(4,4,0) import Data.Complex #endif-#if (defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707) || defined(MIN_VERSION_tagged)+#if __GLASGOW_HASKELL__ >= 707 || defined(MIN_VERSION_tagged) import Data.Proxy #endif+#if __GLASGOW_HASKELL__ >= 800 || defined(MIN_VERSION_semigroups)+import qualified Data.Semigroup as Semigroup+#endif #ifdef MIN_VERSION_tagged import Data.Tagged #endif+#if __GLASGOW_HASKELL__ >= 702+import GHC.Generics (U1(..), (:*:)(..), (:.:)(..), Par1(..), Rec1(..), M1(..))+#endif #ifdef HLINT {-# ANN module "hlint: ignore Use section" #-}@@ -53,9 +61,7 @@ -- some Coapplicative class. Categorically every 'Distributive' -- functor is actually a right adjoint, and so it must be 'Representable' -- endofunctor and preserve all limits. This is a fancy way of saying it--- isomorphic to `(->) x` for some x.------ Minimal complete definition: 'distribute' or 'collect'+-- isomorphic to @(->) x@ for some x. -- -- To be distributable a container will need to have a way to consistently -- zip a potentially infinite number of copies of itself. This effectively@@ -64,54 +70,77 @@ -- and no extra information to try to merge together. -- class Functor g => Distributive g where+#if __GLASGOW_HASKELL__ >= 707+ {-# MINIMAL distribute | collect #-}+#endif -- | The dual of 'Data.Traversable.sequenceA' -- -- >>> distribute [(+1),(+2)] 1 -- [2,3] --- -- @'distribute' = 'collect' 'id'@+ -- @+ -- 'distribute' = 'collect' 'id'+ -- 'distribute' . 'distribute' = 'id'+ -- @ distribute :: Functor f => f (g a) -> g (f a) distribute = collect id -- |- -- @'collect' f = 'distribute' . 'fmap' f@+ -- @+ -- 'collect' f = 'distribute' . 'fmap' f+ -- 'fmap' f = 'runIdentity' . 'collect' ('Identity' . f)+ -- 'fmap' 'distribute' . 'collect' f = 'getCompose' . 'collect' ('Compose' . f)+ -- @+ collect :: Functor f => (a -> g b) -> f a -> g (f b) collect f = distribute . fmap f -- | The dual of 'Data.Traversable.sequence' --- -- @'distributeM' = 'fmap' 'unwrapMonad' . 'distribute' . 'WrapMonad'@+ -- @+ -- 'distributeM' = 'fmap' 'unwrapMonad' . 'distribute' . 'WrapMonad'+ -- @ distributeM :: Monad m => m (g a) -> g (m a) distributeM = fmap unwrapMonad . distribute . WrapMonad -- |- -- @'collectM' = 'distributeM' . 'liftM' f@+ -- @+ -- 'collectM' = 'distributeM' . 'liftM' f+ -- @ collectM :: Monad m => (a -> g b) -> m a -> g (m b) collectM f = distributeM . liftM f -- | The dual of 'Data.Traversable.traverse' ----- @'cotraverse' f = 'fmap' f . 'distribute'@-cotraverse :: (Functor f, Distributive g) => (f a -> b) -> f (g a) -> g b+-- @+-- 'cotraverse' f = 'fmap' f . 'distribute'+-- @+cotraverse :: (Distributive g, Functor f) => (f a -> b) -> f (g a) -> g b cotraverse f = fmap f . distribute -- | The dual of 'Data.Traversable.mapM' ----- @'comapM' f = 'fmap' f . 'distributeM'@-comapM :: (Monad m, Distributive g) => (m a -> b) -> m (g a) -> g b+-- @+-- 'comapM' f = 'fmap' f . 'distributeM'+-- @+comapM :: (Distributive g, Monad m) => (m a -> b) -> m (g a) -> g b comapM f = fmap f . distributeM instance Distributive Identity where collect f = Identity . fmap (runIdentity . f) distribute = Identity . fmap runIdentity +#if __GLASGOW_HASKELL__ >= 707 || defined(MIN_VERSION_tagged) instance Distributive Proxy where collect _ _ = Proxy distribute _ = Proxy+#endif +#if defined(MIN_VERSION_tagged) instance Distributive (Tagged t) where collect f = Tagged . fmap (unTagged . f) distribute = Tagged . fmap unTagged+#endif instance Distributive ((->)e) where distribute a e = fmap ($e) a@@ -148,6 +177,24 @@ collect f = Monoid.Sum . fmap (Monoid.getSum . f) distribute = Monoid.Sum . fmap Monoid.getSum +#if __GLASGOW_HASKELL__ >= 800 || defined(MIN_VERSION_semigroups)+instance Distributive Semigroup.Min where+ collect f = Semigroup.Min . fmap (Semigroup.getMin . f)+ distribute = Semigroup.Min . fmap Semigroup.getMin++instance Distributive Semigroup.Max where+ collect f = Semigroup.Max . fmap (Semigroup.getMax . f)+ distribute = Semigroup.Max . fmap Semigroup.getMax++instance Distributive Semigroup.First where+ collect f = Semigroup.First . fmap (Semigroup.getFirst . f)+ distribute = Semigroup.First . fmap Semigroup.getFirst++instance Distributive Semigroup.Last where+ collect f = Semigroup.Last . fmap (Semigroup.getLast . f)+ distribute = Semigroup.Last . fmap Semigroup.getLast+#endif+ #if MIN_VERSION_base(4,4,0) instance Distributive Complex where distribute wc = fmap realP wc :+ fmap imagP wc where@@ -155,4 +202,31 @@ -- constraints on older versions of base realP (r :+ _) = r imagP (_ :+ i) = i+#endif++-- | 'fmapCollect' is a viable default definition for 'fmap' given+-- a 'Distributive' instance defined in terms of 'collect'.+fmapCollect :: Distributive f => (a -> b) -> f a -> f b+fmapCollect f = runIdentity . collect (Identity . f)++#if __GLASGOW_HASKELL__ >= 702+instance Distributive U1 where+ distribute _ = U1++instance (Distributive a, Distributive b) => Distributive (a :*: b) where+ distribute f = distribute (fmap fstP f) :*: distribute (fmap sndP f) where+ fstP (l :*: _) = l+ sndP (_ :*: r) = r++instance (Distributive a, Distributive b) => Distributive (a :.: b) where+ distribute = Comp1 . fmap distribute . distribute . fmap unComp1++instance Distributive Par1 where+ distribute = Par1 . fmap unPar1++instance Distributive f => Distributive (Rec1 f) where+ distribute = Rec1 . distribute . fmap unRec1++instance Distributive f => Distributive (M1 i c f) where+ distribute = M1 . distribute . fmap unM1 #endif