distributive-0.3/0000755000000000000000000000000012072332653012262 5ustar0000000000000000distributive-0.3/.ghci0000644000000000000000000000012512072332653013173 0ustar0000000000000000:set -isrc -idist/build/autogen -optP-include -optPdist/build/autogen/cabal_macros.h distributive-0.3/.travis.yml0000644000000000000000000000116712072332653014400 0ustar0000000000000000language: 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" distributive-0.3/.vim.custom0000644000000000000000000000137712072332653014377 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.3/CHANGELOG.markdown0000644000000000000000000000027612072332653015322 0ustar00000000000000000.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.3/config0000644000000000000000000000120612072332653013451 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.3/distributive.cabal0000644000000000000000000000265212072332653015770 0ustar0000000000000000name: distributive category: Data Structures version: 0.3 license: BSD3 cabal-version: >= 1.8 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 Edward A. Kmett synopsis: Haskell 98 Distributive functors -- Dual to Traversable description: Haskell 98 Distributive functors -- Dual to Traversable 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, transformers-compat >= 0.1 && < 0.2 hs-source-dirs: src exposed-modules: Data.Distributive 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 distributive-0.3/LICENSE0000644000000000000000000000265312072332652013274 0ustar0000000000000000Copyright 2011 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. 3. Neither the name of the author nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission. 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.3/README.markdown0000644000000000000000000000202012072332653014755 0ustar0000000000000000distributive ============ [![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 distributive-0.3/Setup.lhs0000644000000000000000000000364712072332653014104 0ustar0000000000000000#!/usr/bin/runhaskell \begin{code} {-# OPTIONS_GHC -Wall #-} module Main (main) where 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 = 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} distributive-0.3/travis-cabal-apt-install0000755000000000000000000000100712072332653017004 0ustar0000000000000000#!/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 "$@" distributive-0.3/src/0000755000000000000000000000000012072332652013050 5ustar0000000000000000distributive-0.3/src/Data/0000755000000000000000000000000012072332652013721 5ustar0000000000000000distributive-0.3/src/Data/Distributive.hs0000644000000000000000000000701012072332652016730 0ustar0000000000000000----------------------------------------------------------------------------- -- | -- Module : Data.Distributive -- Copyright : (C) 2011-2012 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) 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 distributive-0.3/tests/0000755000000000000000000000000012072332652013423 5ustar0000000000000000distributive-0.3/tests/doctests.hs0000644000000000000000000000152712072332652015614 0ustar0000000000000000module 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