packages feed

distributive 0.2.2 → 0.3

raw patch · 12 files changed

+341/−100 lines, 12 filesdep +directorydep +doctestdep +filepathdep ~basebuild-type:Customsetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies added: directory, doctest, filepath, transformers-compat

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Data.Distributive: instance Distributive f => Distributive (Backwards f)
+ Data.Distributive: instance Distributive f => Distributive (Reverse f)

Files

+ .ghci view
@@ -0,0 +1,1 @@+:set -isrc -idist/build/autogen -optP-include -optPdist/build/autogen/cabal_macros.h
+ .travis.yml view
@@ -0,0 +1,25 @@+language: haskell+before_install:+  # Uncomment whenever hackage is down.+  # - mkdir -p ~/.cabal && cp config ~/.cabal/config && cabal update++  # Try installing some of the build-deps with apt-get for speed.+  - ./travis-cabal-apt-install --only-dependencies --force-reinstall $mode++install:+  - cabal configure -flib-Werror $mode+  - cabal build++script:+  - $script++notifications:+  irc:+    channels:+      - "irc.freenode.org#haskell-lens"+    skip_join: true+    template:+      - "\x0313distributive\x03/\x0306%{branch}\x03 \x0314%{commit}\x03 %{build_url} %{message}"++env:+  - mode="--enable-tests" script="cabal test"
+ .vim.custom view
@@ -0,0 +1,31 @@+" 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 <F2> :exec ":!hasktags -x -c --ignore src"<CR><CR>++" 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"
+ CHANGELOG.markdown view
@@ -0,0 +1,4 @@+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+
− Data/Distributive.hs
@@ -1,87 +0,0 @@--------------------------------------------------------------------------------- |--- Module      :  Data.Distributive--- Copyright   :  (C) 2011 Edward Kmett--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Edward Kmett <ekmett@gmail.com>--- Stability   :  provisional--- Portability :  portable---------------------------------------------------------------------------------module Data.Distributive -  ( Distributive(..)-  , cotraverse-  , comapM-  ) where--import Control.Applicative-import Control.Monad (liftM)-import Control.Monad.Trans.Identity-import Control.Monad.Trans.Reader-import Control.Monad.Instances ()-import Data.Functor.Identity-import Data.Functor.Product-import Data.Functor.Compose---- | This is the categorical dual of 'Traversable'. However, there appears--- to be little benefit to allow the distribution via an arbitrary comonad--- so we restrict ourselves to 'Functor'.--- --- Minimal complete definition: 'distribute' or 'collect'------ 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-  -- | The dual of 'Data.Traversable.sequence'-  -- -  -- > distribute = collect id-  distribute  :: Functor f => f (g a) -> g (f a)-  distribute  = collect id--  -- | -  -- > collect = distribute . fmap f-  collect     :: Functor f => (a -> g b) -> f a -> g (f b)-  collect f   = distribute . fmap f--  -- | -  -- > 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--cotraverse :: (Functor f, Distributive g) => (f a -> b) -> f (g a) -> g b-cotraverse f = fmap f . distribute--comapM :: (Monad m, Distributive g) => (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--instance Distributive ((->)e) where-  distribute a e = fmap ($e) a--instance Distributive g => Distributive (ReaderT e g) where-  distribute a = ReaderT $ \e -> collect (flip runReaderT e) a--instance Distributive g => Distributive (IdentityT g) where-  collect f = IdentityT . collect (runIdentityT . f)--instance (Distributive f, Distributive g) => Distributive (Compose f g) where-  distribute = Compose . fmap distribute . collect getCompose--instance (Distributive f, Distributive g) => Distributive (Product f g) where-  -- distribute  :: Functor w => w (Product f g a) -> Product f g (w a)-  distribute wp = Pair (collect fstP wp) (collect sndP wp) where -    fstP (Pair a _) = a-    sndP (Pair _ b) = b
+ README.markdown view
@@ -0,0 +1,32 @@+distributive+============++[![Build Status](https://secure.travis-ci.org/ekmett/distributive.png?branch=master)](http://travis-ci.org/ekmett/distributive)++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
Setup.lhs view
@@ -1,7 +1,44 @@ #!/usr/bin/runhaskell-> module Main (main) where+\begin{code}+{-# OPTIONS_GHC -Wall #-}+module Main (main) where -> import Distribution.Simple+import Data.List ( nub )+import Data.Version ( showVersion )+import Distribution.Package ( PackageName(PackageName), PackageId, InstalledPackageId, packageVersion, packageName )+import Distribution.PackageDescription ( PackageDescription(), TestSuite(..) )+import Distribution.Simple ( defaultMainWithHooks, UserHooks(..), simpleUserHooks )+import Distribution.Simple.Utils ( rewriteFile, createDirectoryIfMissingVerbose )+import Distribution.Simple.BuildPaths ( autogenModulesDir )+import Distribution.Simple.Setup ( BuildFlags(buildVerbosity), fromFlag )+import Distribution.Simple.LocalBuildInfo ( withLibLBI, withTestLBI, LocalBuildInfo(), ComponentLocalBuildInfo(componentPackageDeps) )+import Distribution.Verbosity ( Verbosity )+import System.FilePath ( (</>) ) -> main :: IO ()-> main = defaultMain+main :: IO ()+main = defaultMainWithHooks simpleUserHooks+  { buildHook = \pkg lbi hooks flags -> do+     generateBuildModule (fromFlag (buildVerbosity flags)) pkg lbi+     buildHook simpleUserHooks pkg lbi hooks flags+  }++generateBuildModule :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()+generateBuildModule verbosity pkg lbi = do+  let dir = autogenModulesDir lbi+  createDirectoryIfMissingVerbose verbosity True dir+  withLibLBI pkg lbi $ \_ libcfg -> do+    withTestLBI pkg lbi $ \suite suitecfg -> do+      rewriteFile (dir </> "Build_" ++ testName suite ++ ".hs") $ unlines+        [ "module Build_" ++ testName suite ++ " where"+        , "deps :: [String]"+        , "deps = " ++ (show $ formatdeps (testDeps libcfg suitecfg))+        ]+  where+    formatdeps = map (formatone . snd)+    formatone p = case packageName p of+      PackageName n -> n ++ "-" ++ showVersion (packageVersion p)++testDeps :: ComponentLocalBuildInfo -> ComponentLocalBuildInfo -> [(InstalledPackageId, PackageId)]+testDeps xs ys = nub $ componentPackageDeps xs ++ componentPackageDeps ys++\end{code}
+ config view
@@ -0,0 +1,16 @@+-- 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.cabal view
@@ -1,28 +1,59 @@ name:          distributive category:      Data Structures-version:       0.2.2+version:       0.3 license:       BSD3-cabal-version: >= 1.6+cabal-version: >= 1.8 license-file:  LICENSE author:        Edward A. Kmett maintainer:    Edward A. Kmett <ekmett@gmail.com> stability:     provisional homepage:      http://github.com/ekmett/distributive/+bug-reports:   http://github.com/ekmett/distributive/issues copyright:     Copyright (C) 2011 Edward A. Kmett synopsis:      Haskell 98 Distributive functors -- Dual to Traversable description:   Haskell 98 Distributive functors -- Dual to Traversable-build-type:    Simple+build-type:    Custom+extra-source-files:+  .ghci+  .travis.yml+  .vim.custom+  config+  travis-cabal-apt-install+  CHANGELOG.markdown+  README.markdown  source-repository head   type: git   location: git://github.com/ekmett/distributive.git +flag lib-Werror+  manual: True+  default: False+ library-  build-depends: -    base         >= 4 && < 5,-    transformers >= 0.2 && < 0.4+  build-depends:+    base                >= 4   && < 5,+    transformers        >= 0.2 && < 0.4,+    transformers-compat >= 0.1 && < 0.2 -  exposed-modules:-    Data.Distributive+  hs-source-dirs:  src+  exposed-modules: Data.Distributive -  ghc-options: -Wall+  if flag(lib-Werror)+    ghc-options: -Werror+  else+    ghc-options: -Wall++-- Verify the results of the examples+test-suite doctests+  type:    exitcode-stdio-1.0+  main-is: doctests.hs+  build-depends:+    base      >= 4,+    directory >= 1.0,+    doctest   >= 0.9.1,+    filepath  >= 1.2+  ghc-options: -Wall -threaded+  if impl(ghc<7.6.1)+    ghc-options: -Werror+  hs-source-dirs: tests
+ src/Data/Distributive.hs view
@@ -0,0 +1,105 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Distributive+-- Copyright   :  (C) 2011-2012 Edward Kmett+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+----------------------------------------------------------------------------+module Data.Distributive+  ( Distributive(..)+  , cotraverse+  , comapM+  ) where++import Control.Applicative+import Control.Applicative.Backwards+import Control.Monad (liftM)+import Control.Monad.Instances ()+import Control.Monad.Trans.Identity+import Control.Monad.Trans.Reader+import Data.Functor.Compose+import Data.Functor.Identity+import Data.Functor.Product+import Data.Functor.Reverse++{-# ANN module "ignore Use section" #-}++-- | This is the categorical dual of 'Traversable'. However, there appears+-- to be little benefit to allow the distribution via an arbitrary comonad+-- so we restrict ourselves to 'Functor'.+--+-- Minimal complete definition: 'distribute' or 'collect'+--+-- 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+  -- | The dual of 'Data.Traversable.sequenceA'+  --+  -- >>> distribute [(+1),(+2)] 1+  -- [2,3]+  --+  -- @'distribute' = 'collect' 'id'@+  distribute  :: Functor f => f (g a) -> g (f a)+  distribute  = collect id++  -- |+  -- @'collect' = 'distribute' . 'fmap' 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 :: (Functor f, Distributive g) => (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++instance Distributive Identity where+  collect f = Identity . fmap (runIdentity . f)+  distribute = Identity . fmap runIdentity++instance Distributive ((->)e) where+  distribute a e = fmap ($e) a++instance Distributive g => Distributive (ReaderT e g) where+  distribute a = ReaderT $ \e -> collect (flip runReaderT e) a++instance Distributive g => Distributive (IdentityT g) where+  collect f = IdentityT . collect (runIdentityT . f)++instance (Distributive f, Distributive g) => Distributive (Compose f g) where+  distribute = Compose . fmap distribute . collect getCompose++instance (Distributive f, Distributive g) => Distributive (Product f g) where+  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++instance Distributive f => Distributive (Reverse f) where+  distribute = Reverse . collect getReverse
+ tests/doctests.hs view
@@ -0,0 +1,30 @@+module Main where++import Build_doctests (deps)+import Control.Applicative+import Control.Monad+import Data.List+import System.Directory+import System.FilePath+import Test.DocTest++main :: IO ()+main = getSources >>= \sources -> doctest $+    "-isrc"+  : "-idist/build/autogen"+  : "-optP-include"+  : "-optPdist/build/autogen/cabal_macros.h"+  : "-hide-all-packages"+  : map ("-package="++) deps ++ sources++getSources :: IO [FilePath]+getSources = filter (isSuffixOf ".hs") <$> go "src"+  where+    go dir = do+      (dirs, files) <- getFilesAndDirectories dir+      (files ++) . concat <$> mapM go dirs++getFilesAndDirectories :: FilePath -> IO ([FilePath], [FilePath])+getFilesAndDirectories dir = do+  c <- map (dir </>) . filter (`notElem` ["..", "."]) <$> getDirectoryContents dir+  (,) <$> filterM doesDirectoryExist c <*> filterM doesFileExist c
+ travis-cabal-apt-install view
@@ -0,0 +1,16 @@+#!/bin/sh+set -eu++sudo apt-get -q update+sudo apt-get -q -y install dctrl-tools++# Try installing some of the build-deps with apt-get for speed.+eval "$(+  printf '%s' "grep-aptavail -n -sPackage '(' -FFALSE -X FALSE ')'"+  2>/dev/null cabal install "$@" --dry-run -v | \+  sed -nre "s/^([^ ]+)-[0-9.]+ \(.*$/ -o '(' -FPackage -X libghc-\1-dev ')'/p" | \+  xargs -d'\n'+)" | sort -u | xargs -d'\n' sudo apt-get -q -y install -- libghc-quickcheck2-dev++# Install whatever is still needed with cabal.+cabal install "$@"