distributive (empty) → 0.1
raw patch · 4 files changed
+147/−0 lines, 4 filesdep +basedep +transformerssetup-changed
Dependencies added: base, transformers
Files
- Data/Distributive.hs +82/−0
- LICENSE +30/−0
- Setup.lhs +7/−0
- distributive.cabal +28/−0
+ Data/Distributive.hs view
@@ -0,0 +1,82 @@+-----------------------------------------------------------------------------+-- |+-- 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(..)+ , fmapDefault+ , 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++-- | 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)++-- | Every 'Distributive' is a 'Functor'. This is a valid default definition.+fmapDefault :: Distributive g => (a -> b) -> g a -> g b+fmapDefault f = cotraverse (f . runIdentity) . Identity+
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright 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.
+ Setup.lhs view
@@ -0,0 +1,7 @@+#!/usr/bin/runhaskell+> module Main (main) where++> import Distribution.Simple++> main :: IO ()+> main = defaultMain
+ distributive.cabal view
@@ -0,0 +1,28 @@+name: distributive+category: Data Structures+version: 0.1+license: BSD3+cabal-version: >= 1.6+license-file: LICENSE+author: Edward A. Kmett+maintainer: Edward A. Kmett <ekmett@gmail.com>+stability: provisional+homepage: http://github.com/ekmett/distributive/+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++source-repository head+ type: git+ location: git://github.com/ekmett/distributive.git++library+ build-depends: + base >= 4 && < 4.4,+ transformers >= 0.2.0 && < 0.3++ exposed-modules:+ Data.Distributive++ ghc-options: -Wall