distributive-0.6.2.1/0000755000000000000000000000000007346545000012564 5ustar0000000000000000distributive-0.6.2.1/.hlint.yaml0000755000000000000000000000011507346545000014644 0ustar0000000000000000- arguments: [--cpp-define=HLINT, --cpp-ansi] - ignore: {name: Use section} distributive-0.6.2.1/.vim.custom0000755000000000000000000000137707346545000014704 0ustar0000000000000000" Add the following to your .vimrc to automatically load this on startup " if filereadable(".vim.custom") " so .vim.custom " endif function StripTrailingWhitespace() let myline=line(".") let mycolumn = col(".") silent %s/ *$// call cursor(myline, mycolumn) endfunction " enable syntax highlighting syntax on " search for the tags file anywhere between here and / set tags=TAGS;/ " highlight tabs and trailing spaces set listchars=tab:‗‗,trail:‗ set list " f2 runs hasktags map :exec ":!hasktags -x -c --ignore src" " strip trailing whitespace before saving " au BufWritePre *.hs,*.markdown silent! cal StripTrailingWhitespace() " rebuild hasktags after saving au BufWritePost *.hs silent! :exec ":!hasktags -x -c --ignore src" distributive-0.6.2.1/CHANGELOG.markdown0000755000000000000000000000441207346545000015623 0ustar00000000000000000.6.2.1 [2020.12.30] -------------------- * The build-type has been changed from `Custom` to `Simple`. To achieve this, the `doctests` test suite has been removed in favor of using [`cabal-docspec`](https://github.com/phadej/cabal-extras/tree/master/cabal-docspec) to run the doctests. 0.6.2 [2020.04.10] ------------------ * Make the `Distributive` instance for `Tagged` poly-kinded. 0.6.1 [2019.09.06] ------------------ * Add a `Distributive` instance for `WrappedMonad m`. 0.6 [2018.07.02] ---------------- * Remove `fmapCollect`. (See [here](https://github.com/ekmett/distributive/commit/1020655f15714514048d0dc842ffe4adcec89a7b) for an explanation of why it was removed.) * Avoid incurring some dependencies when using recent GHCs. 0.5.3 ----- * Support `doctest-0.12` 0.5.2 ----- * Revamp `Setup.hs` to use `cabal-doctest`. This makes `distributive` build with `Cabal-1.25`, and makes the `doctest`s work with `cabal new-build` and sandboxes. * Fix bugs in `Data.Distributive.Generic` that cause generic `Distributive` instances not to work properly for datatypes with recursive types * Add `genericCollect` to `Data.Distributive.Generic`, and switch the underlying machinery in that module to work on a `collect`-like method instead of a `distribute`-like one * Add a test suite for regression-testing `Data.Distributive.Generic` 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 0.5.0.1 ------- * Fix builds on GHC 7.2 0.5 --- * Added flags for removing some dependencies. * Support `doctests` when building to non-standard locations (such as when using `stack`.) * Support `base-orphans` 0.4.4 ----- * `transformers 0.4` compatibility 0.4.3.1 ----- * Fixed builds with older versions of GHC 0.4.2 ------- * Added `Data.Distributive.Generic`. 0.4.1 ----- * `Control.Monad.Instances` is deprecated in GHC 7.8. Don't import it there. 0.4 --- * Added support for `Data.Tagged` and `Data.Proxy`. 0.3.1 ----- * Minor documentation fix 0.3 --- * Added instances for `Control.Applicative.Backwards` and `Data.Functor.Reverse` from `transformers` 0.3, taking them from `transformers-compat` if necessary for `transformers` 0.2 distributive-0.6.2.1/LICENSE0000644000000000000000000000236407346545000013576 0ustar0000000000000000Copyright 2011-2016 Edward Kmett All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. 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. THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. distributive-0.6.2.1/README.markdown0000755000000000000000000000225007346545000015267 0ustar0000000000000000distributive ============ [![Hackage](https://img.shields.io/hackage/v/distributive.svg)](https://hackage.haskell.org/package/distributive) [![Build Status](https://github.com/ekmett/distributive/workflows/Haskell-CI/badge.svg)](https://github.com/ekmett/distributive/actions?query=workflow%3AHaskell-CI) This package provides the notion that is categorically dual to `Traversable`. A `Distributive` `Functor` is one that you can push any functor inside of. ```haskell distribute :: (Functor f, Distributive g) => f (g a) -> g (f a) ``` Compare this with the corresponding Traversable notion, `sequenceA`. ```haskell sequenceA :: (Applicative f, Traversable g) => g (f a) -> f (g a) ``` This package includes instances for common types, and includes other methods similar to `traverse` which fuse the use of `fmap`. We only require `Functor` rather than some dual notion to `Applicative`, because the latter cannot meaningfully exist in Haskell since all comonoids there are trivial. Contact Information ------------------- Contributions and bug reports are welcome! Please feel free to contact me through github or on the #haskell IRC channel on irc.freenode.net. -Edward Kmett distributive-0.6.2.1/Setup.lhs0000644000000000000000000000014207346545000014371 0ustar0000000000000000\begin{code} import Distribution.Simple (defaultMain) main :: IO () main = defaultMain \end{code} distributive-0.6.2.1/config0000755000000000000000000000120607346545000013756 0ustar0000000000000000-- This provides a custom ~/.cabal/config file for use when hackage is down that should work on unix -- -- This is particularly useful for travis-ci to get it to stop complaining -- about a broken build when everything is still correct on our end. -- -- This uses Luite Stegeman's mirror of hackage provided by his 'hdiff' site instead -- -- To enable this, uncomment the before_script in .travis.yml remote-repo: hdiff.luite.com:http://hdiff.luite.com/packages/archive remote-repo-cache: ~/.cabal/packages world-file: ~/.cabal/world build-summary: ~/.cabal/logs/build.log remote-build-reporting: anonymous install-dirs user install-dirs global distributive-0.6.2.1/distributive.cabal0000644000000000000000000000547207346545000016275 0ustar0000000000000000name: distributive category: Data Structures version: 0.6.2.1 license: BSD3 cabal-version: >= 1.10 license-file: LICENSE author: Edward A. Kmett maintainer: Edward A. Kmett stability: provisional homepage: http://github.com/ekmett/distributive/ bug-reports: http://github.com/ekmett/distributive/issues copyright: Copyright (C) 2011-2016 Edward A. Kmett synopsis: Distributive functors -- Dual to Traversable description: Distributive functors -- Dual to @Traversable@ build-type: Simple tested-with: GHC == 7.0.4 , GHC == 7.2.2 , GHC == 7.4.2 , GHC == 7.6.3 , GHC == 7.8.4 , GHC == 7.10.3 , GHC == 8.0.2 , GHC == 8.2.2 , GHC == 8.4.4 , GHC == 8.6.5 , GHC == 8.8.4 , GHC == 8.10.3 extra-source-files: .hlint.yaml .vim.custom config CHANGELOG.markdown README.markdown source-repository head type: git location: git://github.com/ekmett/distributive.git flag semigroups manual: True default: True description: You can disable the use of the `semigroups` package using `-f-semigroups`. . 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 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. library build-depends: base >= 4 && < 5, base-orphans >= 0.5.2 && < 1, transformers >= 0.3 && < 0.6 hs-source-dirs: src exposed-modules: Data.Distributive if impl(ghc>=7.2) exposed-modules: Data.Distributive.Generic if flag(tagged) build-depends: tagged >= 0.7 && < 1 if impl(ghc>=7.2 && < 7.6) build-depends: ghc-prim if impl(ghc < 8.0) if flag(semigroups) build-depends: semigroups >= 0.13 && < 1 if impl(ghc < 7.8) hs-source-dirs: src-compat other-modules: Data.Coerce ghc-options: -Wall if impl(ghc >= 9.0) -- these flags may abort compilation with GHC-8.10 -- https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3295 ghc-options: -Winferred-safe-imports -Wmissing-safe-haskell-mode default-language: Haskell2010 test-suite spec type: exitcode-stdio-1.0 hs-source-dirs: tests build-tool-depends: hspec-discover:hspec-discover build-depends: base >= 4 && < 5, distributive, generic-deriving >= 1.11 && < 2, hspec >= 2 && < 3 main-is: Spec.hs other-modules: GenericsSpec ghc-options: -Wall -threaded -rtsopts default-language: Haskell2010 distributive-0.6.2.1/src-compat/Data/0000755000000000000000000000000007346545000015505 5ustar0000000000000000distributive-0.6.2.1/src-compat/Data/Coerce.hs0000644000000000000000000000030007346545000017232 0ustar0000000000000000-- This is a shim for GHC before 7.8. Cabal ignores it -- for GHC 7.8 and later. module Data.Coerce (coerce) where import Unsafe.Coerce (unsafeCoerce) coerce :: a -> b coerce = unsafeCoerce distributive-0.6.2.1/src/Data/0000755000000000000000000000000007346545000014224 5ustar0000000000000000distributive-0.6.2.1/src/Data/Distributive.hs0000644000000000000000000002304707346545000017243 0ustar0000000000000000{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE ScopedTypeVariables #-} #if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif #if __GLASGOW_HASKELL__ >= 706 {-# LANGUAGE PolyKinds #-} #endif ----------------------------------------------------------------------------- -- | -- Module : Data.Distributive -- Copyright : (C) 2011-2016 Edward Kmett -- License : BSD-style (see the file LICENSE) -- -- Maintainer : Edward Kmett -- Stability : provisional -- Portability : portable -- ---------------------------------------------------------------------------- module Data.Distributive ( Distributive(..) , cotraverse , comapM ) where import Control.Applicative import Control.Applicative.Backwards import Control.Monad (liftM) #if __GLASGOW_HASKELL__ < 707 import Control.Monad.Instances () #endif import Control.Monad.Trans.Identity import Control.Monad.Trans.Reader import Data.Coerce import Data.Functor.Compose import Data.Functor.Identity import Data.Functor.Product import Data.Functor.Reverse import qualified Data.Monoid as Monoid import Data.Orphans () #if MIN_VERSION_base(4,4,0) import Data.Complex #endif #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" #-} #endif -- | This is the categorical dual of 'Traversable'. -- -- Due to the lack of non-trivial comonoids in Haskell, we can restrict -- ourselves to requiring a 'Functor' rather than -- 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 -- is 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 -- means that the holes in all values of that type, must have the same -- cardinality, fixed sized vectors, infinite streams, functions, etc. -- 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' . 'distribute' = 'id' -- @ distribute :: Functor f => f (g a) -> g (f a) distribute = collect id -- | -- @ -- '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 :: Monad m => m (g a) -> g (m a) distributeM = fmap unwrapMonad . distribute . WrapMonad -- | -- @ -- '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 :: (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 :: (Distributive g, Monad m) => (m a -> b) -> m (g a) -> g b comapM f = fmap f . distributeM instance Distributive Identity where collect = coerce (fmap :: (a -> b) -> f a -> f b) :: forall a b f . Functor f => (a -> Identity b) -> f a -> Identity (f b) 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 = coerce (fmap :: (a -> b) -> f a -> f b) :: forall a b f . Functor f => (a -> Tagged t b) -> f a -> Tagged t (f b) distribute = Tagged . fmap unTagged #endif instance Distributive ((->)e) where distribute a e = fmap ($e) a collect f q e = fmap (flip f e) q instance Distributive g => Distributive (ReaderT e g) where distribute a = ReaderT $ \e -> collect (flip runReaderT e) a collect f x = ReaderT $ \e -> collect (\a -> runReaderT (f a) e) x instance Distributive g => Distributive (IdentityT g) where collect = coerce (collect :: (a -> g b) -> f a -> g (f b)) :: forall a b f . Functor f => (a -> IdentityT g b) -> f a -> IdentityT g (f b) instance (Distributive f, Distributive g) => Distributive (Compose f g) where distribute = Compose . fmap distribute . collect getCompose collect f = Compose . fmap distribute . collect (coerce f) instance (Distributive f, Distributive g) => Distributive (Product f g) where -- It might be tempting to write a 'collect' implementation that -- composes the passed function with fstP and sndP. This could be bad, -- because it would lead to the passed function being evaluated twice -- for each element of the underlying functor. distribute wp = Pair (collect fstP wp) (collect sndP wp) where fstP (Pair a _) = a sndP (Pair _ b) = b instance Distributive f => Distributive (Backwards f) where distribute = Backwards . collect forwards collect = coerce (collect :: (a -> f b) -> g a -> f (g b)) :: forall g a b . Functor g => (a -> Backwards f b) -> g a -> Backwards f (g b) instance Distributive f => Distributive (Reverse f) where distribute = Reverse . collect getReverse collect = coerce (collect :: (a -> f b) -> g a -> f (g b)) :: forall g a b . Functor g => (a -> Reverse f b) -> g a -> Reverse f (g b) instance Distributive Monoid.Dual where collect = coerce (fmap :: (a -> b) -> f a -> f b) :: forall f a b . Functor f => (a -> Monoid.Dual b) -> f a -> Monoid.Dual (f b) distribute = Monoid.Dual . fmap Monoid.getDual instance Distributive Monoid.Product where collect = coerce (fmap :: (a -> b) -> f a -> f b) :: forall f a b . Functor f => (a -> Monoid.Product b) -> f a -> Monoid.Product (f b) distribute = Monoid.Product . fmap Monoid.getProduct instance Distributive Monoid.Sum where collect = coerce (fmap :: (a -> b) -> f a -> f b) :: forall f a b . Functor f => (a -> Monoid.Sum b) -> f a -> Monoid.Sum (f b) distribute = Monoid.Sum . fmap Monoid.getSum #if __GLASGOW_HASKELL__ >= 800 || defined(MIN_VERSION_semigroups) instance Distributive Semigroup.Min where collect = coerce (fmap :: (a -> b) -> f a -> f b) :: forall f a b . Functor f => (a -> Semigroup.Min b) -> f a -> Semigroup.Min (f b) distribute = Semigroup.Min . fmap Semigroup.getMin instance Distributive Semigroup.Max where collect = coerce (fmap :: (a -> b) -> f a -> f b) :: forall f a b . Functor f => (a -> Semigroup.Max b) -> f a -> Semigroup.Max (f b) distribute = Semigroup.Max . fmap Semigroup.getMax instance Distributive Semigroup.First where collect = coerce (fmap :: (a -> b) -> f a -> f b) :: forall f a b . Functor f => (a -> Semigroup.First b) -> f a -> Semigroup.First (f b) distribute = Semigroup.First . fmap Semigroup.getFirst instance Distributive Semigroup.Last where collect = coerce (fmap :: (a -> b) -> f a -> f b) :: forall f a b . Functor f => (a -> Semigroup.Last b) -> f a -> Semigroup.Last (f b) 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 -- Redefine realPart and imagPart to avoid incurring redundant RealFloat -- constraints on older versions of base realP (r :+ _) = r imagP (_ :+ i) = i #endif instance (Distributive m, Monad m) => Distributive (WrappedMonad m) where collect f = WrapMonad . collect (coerce f) #if __GLASGOW_HASKELL__ >= 702 instance Distributive U1 where distribute _ = U1 instance (Distributive a, Distributive b) => Distributive (a :*: b) where -- It might be tempting to write a 'collect' implementation that -- composes the passed function with fstP and sndP. This could be bad, -- because it would lead to the passed function being evaluated twice -- for each element of the underlying functor. distribute f = collect fstP f :*: collect sndP f where fstP (l :*: _) = l sndP (_ :*: r) = r instance (Distributive a, Distributive b) => Distributive (a :.: b) where distribute = Comp1 . fmap distribute . collect unComp1 collect f = Comp1 . fmap distribute . collect (coerce f) instance Distributive Par1 where distribute = Par1 . fmap unPar1 collect = coerce (fmap :: (a -> b) -> f a -> f b) :: forall f a b . Functor f => (a -> Par1 b) -> f a -> Par1 (f b) instance Distributive f => Distributive (Rec1 f) where distribute = Rec1 . collect unRec1 collect = coerce (collect :: (a -> f b) -> g a -> f (g b)) :: forall g a b . Functor g => (a -> Rec1 f b) -> g a -> Rec1 f (g b) instance Distributive f => Distributive (M1 i c f) where distribute = M1 . collect unM1 collect = coerce (collect :: (a -> f b) -> g a -> f (g b)) :: forall g a b . Functor g => (a -> M1 i c f b) -> g a -> M1 i c f (g b) #endif distributive-0.6.2.1/src/Data/Distributive/0000755000000000000000000000000007346545000016701 5ustar0000000000000000distributive-0.6.2.1/src/Data/Distributive/Generic.hs0000644000000000000000000000564507346545000020623 0ustar0000000000000000{-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE FlexibleContexts #-} #if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif ----------------------------------------------------------------------------- -- | -- Module : Data.Distributive -- Copyright : (C) 2011-2016 Edward Kmett -- License : BSD-style (see the file LICENSE) -- -- Maintainer : Edward Kmett -- Stability : provisional -- Portability : portable -- ---------------------------------------------------------------------------- module Data.Distributive.Generic ( GDistributive(..) , genericCollect , genericDistribute ) where import Data.Distributive import GHC.Generics import Data.Coerce -- | 'collect' derived from a 'Generic1' type -- -- This can be used to easily produce a 'Distributive' instance for a -- type with a 'Generic1' instance, -- -- > data V2 a = V2 a a deriving (Show, Functor, Generic1) -- > instance Distributive V2' where collect = genericCollect genericCollect :: (Functor f, Generic1 g, GDistributive (Rep1 g)) => (a -> g b) -> f a -> g (f b) genericCollect f = to1 . gcollect (from1 . f) -- | 'distribute' derived from a 'Generic1' type -- -- It's often more efficient to use 'genericCollect' instead. genericDistribute :: (Functor f, Generic1 g, GDistributive (Rep1 g)) => f (g a) -> g (f a) genericDistribute = to1 . gdistribute . fmap from1 -- Can't distribute over, -- * sums (:+:) -- * K1 -- * V1 class GDistributive g where gcollect :: Functor f => (a -> g b) -> f a -> g (f b) gdistribute :: (GDistributive g, Functor f) => f (g b) -> g (f b) gdistribute = gcollect id {-# INLINE gdistribute #-} instance GDistributive U1 where gcollect _ _ = U1 {-# INLINE gcollect #-} instance (GDistributive a, GDistributive b) => GDistributive (a :*: b) where -- It might be tempting to fuse `gcollect fstP (fmap f x)` into -- `gcollect (fstP . f) x`, but this would lead to a loss of sharing. gcollect f x = gcollect fstP x' :*: gcollect sndP x' where x' = fmap f x fstP (l :*: _) = l sndP (_ :*: r) = r {-# INLINE gcollect #-} instance (Distributive a, GDistributive b) => GDistributive (a :.: b) where gcollect f = Comp1 . fmap gdistribute . collect (coerce f) {-# INLINE gcollect #-} instance GDistributive Par1 where gcollect = coerce (fmap :: (a -> b) -> f a -> f b) :: forall f a b . Functor f => (a -> Par1 b) -> f a -> Par1 (f b) {-# INLINE gcollect #-} instance Distributive f => GDistributive (Rec1 f) where gcollect = coerce (collect :: (a -> f b) -> g a -> f (g b)) :: forall g a b . Functor g => (a -> Rec1 f b) -> g a -> Rec1 f (g b) {-# INLINE gcollect #-} instance GDistributive f => GDistributive (M1 i c f) where gcollect = coerce (gcollect :: (a -> f b) -> g a -> f (g b)) :: forall g a b . Functor g => (a -> M1 i c f b) -> g a -> M1 i c f (g b) {-# INLINE gcollect #-} distributive-0.6.2.1/tests/0000755000000000000000000000000007346545000013726 5ustar0000000000000000distributive-0.6.2.1/tests/GenericsSpec.hs0000644000000000000000000000507607346545000016644 0ustar0000000000000000{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} #if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE DeriveGeneric #-} #endif ----------------------------------------------------------------------------- -- | -- Module : GenericSpec -- Copyright : (C) 2011-2016 Edward Kmett -- License : BSD-style (see the file LICENSE) -- -- Maintainer : Edward Kmett -- Stability : provisional -- -- Tests for generically derived 'Distributive' instances. ---------------------------------------------------------------------------- module GenericsSpec (main, spec) where import Test.Hspec #if __GLASGOW_HASKELL__ >= 702 import Data.Distributive (Distributive(..)) import Data.Distributive.Generic (genericCollect, genericDistribute) # if __GLASGOW_HASKELL__ >= 706 import Generics.Deriving.Base hiding (Rep) # else import qualified Generics.Deriving.TH as Generics (deriveAll1) # endif #endif main :: IO () main = hspec spec spec :: Spec #if __GLASGOW_HASKELL__ < 702 spec = return () #else spec = do describe "Id" $ it "distribute idExample = idExample" $ distribute idExample `shouldBe` idExample describe "Stream" $ it "runId (shead (stail (distribute streamExample))) = 1" $ runId (shead (stail (distribute streamExample))) `shouldBe` 1 describe "PolyRec" $ it "runId (plast (runId (pinit (distribute polyRecExample)))) = 1" $ runId (plast (runId (pinit (distribute polyRecExample)))) `shouldBe` 1 newtype Id a = Id { runId :: a } deriving (Eq, Functor, Show) instance Distributive Id where collect = genericCollect distribute = genericDistribute idExample :: Id (Id Int) idExample = Id (Id 42) data Stream a = (:>) { shead :: a, stail :: Stream a } deriving Functor instance Distributive Stream where collect = genericCollect distribute = genericDistribute streamExample :: Id (Stream Int) streamExample = Id $ let s = 0 :> fmap (+1) s in s data PolyRec a = PolyRec { pinit :: Id (PolyRec a), plast :: a } deriving Functor instance Distributive PolyRec where collect = genericCollect distribute = genericDistribute polyRecExample :: Id (PolyRec Int) polyRecExample = Id $ let p = PolyRec (Id $ fmap (+1) p) 0 in p # if __GLASGOW_HASKELL__ >= 706 deriving instance Generic1 Id deriving instance Generic1 Stream deriving instance Generic1 PolyRec # else $(Generics.deriveAll1 ''Id) $(Generics.deriveAll1 ''Stream) $(Generics.deriveAll1 ''PolyRec) # endif #endif distributive-0.6.2.1/tests/Spec.hs0000644000000000000000000000005407346545000015153 0ustar0000000000000000{-# OPTIONS_GHC -F -pgmF hspec-discover #-}