packages feed

reducers (empty) → 0.1

raw patch · 17 files changed

+1371/−0 lines, 17 filesdep +arraydep +basedep +bytestringsetup-changed

Dependencies added: array, base, bytestring, containers, fingertree, hashable, parallel, semigroupoids, semigroups, text, transformers, unordered-containers

Files

+ Data/Generator.hs view
@@ -0,0 +1,203 @@+{-# LANGUAGE UndecidableInstances, FlexibleContexts, MultiParamTypeClasses, FlexibleInstances, TypeFamilies, CPP #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Generator+-- Copyright   :  (c) Edward Kmett 2009+-- License     :  BSD-style+-- Maintainer  :  ekmett@gmail.com+-- Stability   :  experimental+-- Portability :  portable+--+-- A 'Generator' @c@ is a possibly-specialized container, which contains values of +-- type 'Elem' @c@, and which knows how to efficiently apply a 'Reducer' to extract+-- an answer.+--+-- Since a 'Generator' is not polymorphic in its contents, it is more specialized+-- than "Data.Foldable.Foldable", and a 'Reducer' may supply efficient left-to-right+-- and right-to-left reduction strategies that a 'Generator' may avail itself of.+-----------------------------------------------------------------------------++module Data.Generator+  (+  -- * Generators+    Generator(..)+  -- * Generator Transformers+  , Keys(Keys, getKeys)+  , Values(Values, getValues)+  , Char8(Char8, getChar8)+  -- * Combinators+  , reduce+  , mapReduceWith+  , reduceWith+  ) where++import Data.Monoid (Monoid, mappend, mempty)++import Data.Array +import Data.Text (Text)+import qualified Data.Text as Text+import qualified Data.ByteString as Strict (ByteString, foldl')+import qualified Data.ByteString.Char8 as Strict8 (foldl')+import qualified Data.ByteString.Lazy as Lazy (ByteString, toChunks)+import qualified Data.ByteString.Lazy.Char8 as Lazy8 (toChunks)+import Data.Word (Word8)+import Data.FingerTree (Measured, FingerTree)+import Data.Sequence (Seq)+import qualified Data.Set as Set+import Data.Set (Set)+import qualified Data.IntSet as IntSet+import Data.IntSet (IntSet)+import qualified Data.IntMap as IntMap+import Data.IntMap (IntMap)+import qualified Data.HashSet as HashSet+import Data.HashSet (HashSet)+import qualified Data.HashMap.Lazy as HashMap+import Data.HashMap.Lazy (HashMap)+import qualified Data.Map as Map+import Data.Map (Map)+import Data.List.NonEmpty (NonEmpty)+import qualified Data.List.NonEmpty as NonEmpty+import Control.Parallel.Strategies (rseq, parMap)+import Data.Foldable (fold,foldMap)+import Data.Semigroup.Reducer++-- | minimal definition 'mapReduce' or 'mapTo'+class Generator c where+  type Elem c+  mapReduce :: (Reducer e m, Monoid m) => (Elem c -> e) -> c -> m+  mapTo     :: (Reducer e m, Monoid m) => (Elem c -> e) -> m -> c -> m +  mapFrom   :: (Reducer e m, Monoid m) => (Elem c -> e) -> c -> m -> m++  mapReduce f = mapTo f mempty+  mapTo f m = mappend m . mapReduce f+  mapFrom f = mappend . mapReduce f+++instance Generator Strict.ByteString where+  type Elem Strict.ByteString = Word8+  mapTo f = Strict.foldl' (\a -> snoc a . f)++instance Generator Lazy.ByteString where+  type Elem Lazy.ByteString = Word8+  mapReduce f = fold . parMap rseq (mapReduce f) . Lazy.toChunks++instance Generator Text where+  type Elem Text = Char+  mapTo f = Text.foldl' (\a -> snoc a . f)++instance Generator [c] where+  type Elem [c] = c+  mapReduce f = foldr (cons . f) mempty++instance Generator (NonEmpty c) where+  type Elem (NonEmpty c) = c+  mapReduce f = mapReduce f . NonEmpty.toList++instance Measured v e => Generator (FingerTree v e) where+  type Elem (FingerTree v e) = e+  mapReduce f = foldMap (unit . f)++instance Generator (Seq c) where+  type Elem (Seq c) = c+  mapReduce f = foldMap (unit . f)++instance Generator IntSet where+  type Elem IntSet = Int+  mapReduce f = mapReduce f . IntSet.toList++instance Generator (HashSet a) where+  type Elem (HashSet a) = a+  mapReduce f = mapReduce f . HashSet.toList++instance Generator (Set a) where+  type Elem (Set a) = a+  mapReduce f = mapReduce f . Set.toList++instance Generator (IntMap v) where+  type Elem (IntMap v) = (Int,v)+  mapReduce f = mapReduce f . IntMap.toList++instance Generator (Map k v) where+  type Elem (Map k v) = (k,v) +  mapReduce f = mapReduce f . Map.toList++instance Generator (HashMap k v) where+  type Elem (HashMap k v) = (k, v)+  mapReduce f = mapReduce f . HashMap.toList++instance Ix i => Generator (Array i e) where+  type Elem (Array i e) = (i,e)+  mapReduce f = mapReduce f . assocs++-- | a 'Generator' transformer that asks only for the keys of an indexed container+newtype Keys c = Keys { getKeys :: c } ++instance Generator (Keys (IntMap v)) where+  type Elem (Keys (IntMap v)) = Int+  mapReduce f = mapReduce f . IntMap.keys . getKeys++instance Generator (Keys (Map k v)) where+  type Elem (Keys (Map k v)) = k+  mapReduce f = mapReduce f . Map.keys . getKeys++instance Ix i => Generator (Keys (Array i e)) where+  type Elem (Keys (Array i e)) = i+  mapReduce f = mapReduce f . range . bounds . getKeys++-- | a 'Generator' transformer that asks only for the values contained in an indexed container+newtype Values c = Values { getValues :: c } ++instance Generator (Values (IntMap v)) where+  type Elem (Values (IntMap v)) = v+  mapReduce f = mapReduce f . IntMap.elems . getValues++instance Generator (Values (Map k v)) where+  type Elem (Values (Map k v)) = v+  mapReduce f = mapReduce f . Map.elems . getValues++instance Ix i => Generator (Values (Array i e)) where+  type Elem (Values (Array i e)) = e+  mapReduce f = mapReduce f . elems . getValues++-- | a 'Generator' transformer that treats 'Word8' as 'Char'+-- This lets you use a 'ByteString' as a 'Char' source without going through a 'Monoid' transformer like 'UTF8'+newtype Char8 c = Char8 { getChar8 :: c } ++instance Generator (Char8 Strict.ByteString) where+  type Elem (Char8 Strict.ByteString) = Char+  mapTo f m = Strict8.foldl' (\a -> snoc a . f) m . getChar8++instance Generator (Char8 Lazy.ByteString) where+  type Elem (Char8 Lazy.ByteString) = Char+  mapReduce f = fold . parMap rseq (mapReduce f . Char8) . Lazy8.toChunks . getChar8++-- | Apply a 'Reducer' directly to the elements of a 'Generator'+reduce :: (Generator c, Reducer (Elem c) m, Monoid m) => c -> m+reduce = mapReduce id+{-# SPECIALIZE reduce :: (Reducer Word8 m, Monoid m) => Strict.ByteString -> m #-}+{-# SPECIALIZE reduce :: (Reducer Word8 m, Monoid m) => Lazy.ByteString -> m #-}+{-# SPECIALIZE reduce :: (Reducer Char m, Monoid m) => Char8 Strict.ByteString -> m #-}+{-# SPECIALIZE reduce :: (Reducer Char m, Monoid m) => Char8 Lazy.ByteString -> m #-}+{-# SPECIALIZE reduce :: (Reducer c m, Monoid m) => [c] -> m #-}+{-# SPECIALIZE reduce :: (Generator (FingerTree v e), Reducer e m, Monoid m) => FingerTree v e -> m #-}+{-# SPECIALIZE reduce :: (Reducer Char m, Monoid m) => Text -> m #-}+{-# SPECIALIZE reduce :: (Reducer e m, Monoid m) => Seq e -> m #-}+{-# SPECIALIZE reduce :: (Reducer Int m, Monoid m) => IntSet -> m #-}+{-# SPECIALIZE reduce :: (Reducer a m, Monoid m) => Set a -> m #-}+{-# SPECIALIZE reduce :: (Reducer a m, Monoid m) => HashSet a -> m #-}+{-# SPECIALIZE reduce :: (Reducer (Int,v) m, Monoid m) => IntMap v -> m #-}+{-# SPECIALIZE reduce :: (Reducer (k,v) m, Monoid m) => Map k v -> m #-}+{-# SPECIALIZE reduce :: (Reducer (k,v) m, Monoid m) => HashMap k v -> m #-}+{-# SPECIALIZE reduce :: (Reducer Int m, Monoid m) => Keys (IntMap v) -> m #-}+{-# SPECIALIZE reduce :: (Reducer k m, Monoid m) => Keys (Map k v) -> m #-}+{-# SPECIALIZE reduce :: (Reducer v m, Monoid m) => Values (IntMap v) -> m #-}+{-# SPECIALIZE reduce :: (Reducer v m, Monoid m) => Values (Map k v) -> m #-}++mapReduceWith :: (Generator c, Reducer e m, Monoid m) => (m -> n) -> (Elem c -> e) -> c -> n+mapReduceWith f g = f . mapReduce g+{-# INLINE mapReduceWith #-}++reduceWith :: (Generator c, Reducer (Elem c) m, Monoid m) => (m -> n) -> c -> n+reduceWith f = f . reduce+{-# INLINE reduceWith #-}
+ Data/Generator/Combinators.hs view
@@ -0,0 +1,233 @@+{-# LANGUAGE UndecidableInstances, TypeOperators, FlexibleContexts, MultiParamTypeClasses, FlexibleInstances, TypeFamilies #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Generator.Combinators+-- Copyright   :  (c) Edward Kmett 2009+-- License     :  BSD-style+-- Maintainer  :  ekmett@gmail.com+-- Stability   :  experimental+-- Portability :  non-portable (type families, MPTCs)+--+-- Utilities for working with Monoids that conflict with names from the "Prelude",+-- "Data.Foldable", "Control.Monad" or elsewhere. Intended to be imported qualified.+--+-- > import Data.Generator.Combinators as Generator+--+-----------------------------------------------------------------------------++module Data.Generator.Combinators+    (+    -- * Monadic Reduction+      mapM_+    , forM_+    , msum+    -- * Applicative Reduction+    , traverse_+    , for_+    , asum+    -- * Logical Reduction+    , and+    , or+    , any+    , all+    -- * Monoidal Reduction+    , foldMap+    , fold+    , toList +    -- * List-Like Reduction+    , concatMap+    , elem+    , filter+    , filterWith+    --, find+    , sum+    , product+    , notElem+    ) where++import Prelude hiding +  ( mapM_, any, all, elem, filter, concatMap, and, or+  , sum, product, notElem, replicate, cycle, repeat+  )+import Control.Applicative+import Control.Monad (MonadPlus)+import Data.Generator+import Data.Monoid (Monoid(..))+import Data.Semigroup (Sum(..), Product(..), All(..), Any(..), WrappedMonoid(..))+import Data.Semigroup.Applicative (Traversal(..))+import Data.Semigroup.Alternative (Alternate(..))+import Data.Semigroup.Monad (Action(..))+import Data.Semigroup.MonadPlus (MonadSum(..))+import Data.Semigroup.Reducer (Reducer(..))++-- | Efficiently 'mapReduce' a 'Generator' using the 'Traversal' monoid. A specialized version of its namesake from "Data.Foldable"+--+-- @+--     'mapReduce' 'getTraversal'+-- @+traverse_ :: (Generator c, Applicative f) => (Elem c -> f b) -> c -> f ()+traverse_ = mapReduceWith getTraversal+{-# INLINE traverse_ #-}+    +-- | Convenience function as found in "Data.Foldable"+--+-- @+--     'flip' 'traverse_'+-- @+for_ :: (Generator c, Applicative f) => c -> (Elem c -> f b) -> f ()+for_ = flip traverse_+{-# INLINE for_ #-}++-- | The sum of a collection of actions, generalizing 'concat'+--+-- @+--    'reduceWith' 'getAlt'+-- @ +asum :: (Generator c, Alternative f, f a ~ Elem c) => c -> f a+asum = reduceWith getAlternate+{-# INLINE asum #-}++-- | Efficiently 'mapReduce' a 'Generator' using the 'Action' monoid. A specialized version of its namesake from "Data.Foldable" and "Control.Monad"+-- +-- @+--    'mapReduceWith' 'getAction'+-- @ +mapM_ :: (Generator c, Monad m) => (Elem c -> m b) -> c -> m ()+mapM_ = mapReduceWith getAction+{-# INLINE mapM_ #-}++-- | Convenience function as found in "Data.Foldable" and "Control.Monad"+--+-- @+--     'flip' 'mapM_'+-- @+forM_ :: (Generator c, Monad m) => c -> (Elem c -> m b) -> m ()+forM_ = flip mapM_+{-# INLINE forM_ #-}++-- | The sum of a collection of actions, generalizing 'concat'+--+-- @+--     'reduceWith' 'getMonadSum'+-- @+msum :: (Generator c, MonadPlus m, m a ~ Elem c) => c -> m a+msum = reduceWith getMonadSum+{-# INLINE msum #-}++-- | Efficiently 'mapReduce' a 'Generator' using the 'WrappedMonoid' monoid. A specialized version of its namesake from "Data.Foldable"+--+-- @+--     'mapReduceWith' 'unwrapMonoid'+-- @+foldMap :: (Monoid m, Generator c) => (Elem c -> m) -> c -> m+foldMap = mapReduceWith unwrapMonoid+{-# INLINE foldMap #-}++-- | Type specialization of "foldMap" above+concatMap :: Generator c => (Elem c -> [b]) -> c -> [b]+concatMap = foldMap+{-# INLINE concatMap #-}++-- | Efficiently 'reduce' a 'Generator' using the 'WrappedMonoid' monoid. A specialized version of its namesake from "Data.Foldable"+--+-- @+--     'reduceWith' 'unwrapMonoid'+-- @+fold :: (Monoid m, Generator c, Elem c ~ m) => c -> m+fold = reduceWith unwrapMonoid+{-# INLINE fold #-}++-- | Convert any 'Generator' to a list of its contents. Specialization of 'reduce'+toList :: Generator c => c -> [Elem c]+toList = reduce+{-# INLINE toList #-}++-- | Efficiently 'reduce' a 'Generator' that contains values of type 'Bool'+--+-- @+--     'reduceWith' 'getAll'+-- @+and :: (Generator c, Elem c ~ Bool) => c -> Bool+and = reduceWith getAll+{-# INLINE and #-}++-- | Efficiently 'reduce' a 'Generator' that contains values of type 'Bool'+--+-- @+--     'reduceWith' 'getAny'+-- @+or :: (Generator c, Elem c ~ Bool) => c -> Bool+or = reduceWith getAny+{-# INLINE or #-}++-- | Efficiently 'mapReduce' any 'Generator' checking to see if any of its values match the supplied predicate+--+-- @+--     'mapReduceWith' 'getAny'+-- @+any :: Generator c => (Elem c -> Bool) -> c -> Bool+any = mapReduceWith getAny+{-# INLINE any #-}++-- | Efficiently 'mapReduce' any 'Generator' checking to see if all of its values match the supplied predicate+--+-- @+--     'mapReduceWith' 'getAll'+-- @+all :: Generator c => (Elem c -> Bool) -> c -> Bool+all = mapReduceWith getAll+{-# INLINE all #-}++-- | Efficiently sum over the members of any 'Generator'+--+-- @+--     'reduceWith' 'getSum'+-- @+sum :: (Generator c, Num (Elem c)) => c -> Elem c+sum = reduceWith getSum+{-# INLINE sum #-}++-- | Efficiently take the product of every member of a 'Generator'+--+-- @+--     'reduceWith' 'getProduct'+-- @+product :: (Generator c, Num (Elem c)) => c -> Elem c+product = reduceWith getProduct+{-# INLINE product #-}++-- | Check to see if 'any' member of the 'Generator' matches the supplied value+elem :: (Generator c, Eq (Elem c)) => Elem c -> c -> Bool+elem = any . (==)+{-# INLINE elem #-}++-- | Check to make sure that the supplied value is not a member of the 'Generator'+notElem :: (Generator c, Eq (Elem c)) => Elem c -> c -> Bool+notElem x = not . elem x+{-# INLINE notElem #-}++-- | Efficiently 'mapReduce' a subset of the elements in a 'Generator'+filter :: (Generator c, Reducer (Elem c) m, Monoid m) => (Elem c -> Bool) -> c -> m+filter p = foldMap f where+    f x | p x = unit x+        | otherwise = mempty+{-# INLINE filter #-}++-- | Allows idiomatic specialization of filter by proving a function that will be used to transform the output+filterWith :: (Generator c, Reducer (Elem c) m, Monoid m) => (m -> n) -> (Elem c -> Bool) -> c -> n +filterWith f p = f . filter p+{-# INLINE filterWith #-}++{-++-- | A specialization of 'filter' using the 'First' 'Monoid', analogous to 'Data.List.find'+--+-- @+--     'filterWith' 'getFirst'+-- @+find :: Generator c => (Elem c -> Bool) -> c -> Maybe (Elem c)+find = filterWith getFirst+{-# INLINE find #-}++-}
+ Data/Semigroup/Alt.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, GeneralizedNewtypeDeriving, FlexibleContexts #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Semigroup.Alt+-- Copyright   :  (c) Edward Kmett 2009-2011+-- License     :  BSD-style+-- Maintainer  :  ekmett@gmail.com+-- Stability   :  experimental+-- Portability :  non-portable (MPTCs)+--+-- A semigroup for working 'Alt' or 'Plus' +--+-----------------------------------------------------------------------------++module Data.Semigroup.Alt+    ( Alter(..)+    ) where++import Data.Functor.Plus+import Data.Monoid (Monoid(..))+import Data.Semigroup (Semigroup(..))+import Data.Semigroup.Reducer (Reducer(..))++-- | A 'Alter' turns any 'Alt' instance into a 'Semigroup'.++newtype Alter f a = Alter { getAlter :: f a } +    deriving (Functor,Alt,Plus)++instance Alt f => Semigroup (Alter f a) where+    Alter a <> Alter b = Alter (a <!> b) ++instance Plus f => Monoid (Alter f a) where+    mempty = zero+    Alter a `mappend` Alter b = Alter (a <!> b) ++instance Alt f => Reducer (f a) (Alter f a) where+    unit = Alter
+ Data/Semigroup/Alternative.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, GeneralizedNewtypeDeriving, FlexibleContexts, TypeOperators #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Semigroup.Alternative+-- Copyright   :  (c) Edward Kmett 2009-2011+-- License     :  BSD-style+-- Maintainer  :  ekmett@gmail.com+-- Stability   :  experimental+-- Portability :  non-portable (MPTCs)+--+-- A semigroup for working with 'Alternative' 'Functor's.+--+-----------------------------------------------------------------------------++module Data.Semigroup.Alternative+    ( Alternate(..)+    ) where++import Control.Applicative+import Data.Monoid (Monoid(..))+import Data.Semigroup (Semigroup(..))+import Data.Semigroup.Reducer (Reducer(..))++-- | A 'Alternate' turns any 'Alternative' instance into a 'Monoid'.++newtype Alternate f a = Alternate { getAlternate :: f a } +  deriving (Functor,Applicative,Alternative)++instance Alternative f => Semigroup (Alternate f a) where+  Alternate a <> Alternate b = Alternate (a <|> b)+   +instance Alternative f => Monoid (Alternate f a) where+  mempty = empty +  Alternate a `mappend` Alternate b = Alternate (a <|> b) ++instance Alternative f => Reducer (f a) (Alternate f a) where+  unit = Alternate +
+ Data/Semigroup/Applicative.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, GeneralizedNewtypeDeriving, FlexibleContexts, TypeOperators #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Semigroup.Applicative+-- Copyright   :  (c) Edward Kmett 2009+-- License     :  BSD-style+-- Maintainer  :  ekmett@gmail.com+-- Stability   :  experimental+-- Portability :  non-portable (MPTCs)+--+-- Semigroups for working with 'Applicative' 'Functor's.+--+-----------------------------------------------------------------------------++module Data.Semigroup.Applicative +    ( Traversal(..)+    , Ap(..)+    ) where++import Control.Applicative+import Control.Monad (void)+import Data.Monoid (Monoid(..))+import Data.Semigroup (Semigroup(..))+import Data.Semigroup.Reducer (Reducer(..))++-- | A 'Traversal' uses an glues together 'Applicative' actions with (*>)+--   in the manner of 'traverse_' from "Data.Foldable". Any values returned by +--   reduced actions are discarded.+newtype Traversal f = Traversal { getTraversal :: f () } ++instance Applicative f => Semigroup (Traversal f) where+  Traversal a <> Traversal b = Traversal (a *> b)++instance Applicative f => Monoid (Traversal f) where+  mempty = Traversal (pure ())+  Traversal a `mappend` Traversal b = Traversal (a *> b)++instance Applicative f => Reducer (f a) (Traversal f) where+  unit = Traversal . void+  a `cons` Traversal b = Traversal (a *> b)+  Traversal a `snoc` b = Traversal (void (a *> b))++-- | Efficiently avoid needlessly rebinding when using 'snoc' on an action that already returns ()+--   A rewrite rule automatically applies this when possible+snocTraversal :: Reducer (f ()) (Traversal f) => Traversal f -> f () -> Traversal f+snocTraversal a = (<>) a . Traversal+{-# RULES "unitTraversal" unit = Traversal #-}+{-# RULES "snocTraversal" snoc = snocTraversal #-}++newtype Ap f m = Ap { getApp :: f m } +  deriving (Functor,Applicative)++instance (Applicative f, Semigroup m) => Semigroup (Ap f m) where+  (<>) = liftA2 (<>)++instance (Applicative f, Monoid m) => Monoid (Ap f m) where+  mempty = pure mempty+  mappend = liftA2 mappend++instance (Applicative f, Reducer c m) => Reducer (f c) (Ap f m) where+  unit = fmap unit . Ap
+ Data/Semigroup/Apply.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, GeneralizedNewtypeDeriving, FlexibleContexts #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Semigroup.Apply+-- Copyright   :  (c) Edward Kmett 2009-2011+-- License     :  BSD-style+-- Maintainer  :  ekmett@gmail.com+-- Stability   :  experimental+-- Portability :  non-portable (MPTCs)+--+-- Semigroups for working with 'Apply'+--+-----------------------------------------------------------------------------++module Data.Semigroup.Apply+    ( Trav(..)+    , App(..)+    ) where++import Control.Monad (void)+import Data.Functor.Apply+import Data.Semigroup (Semigroup(..))+import Data.Semigroup.Reducer (Reducer(..))++-- | A 'Trav' uses an glues together 'Applicative' actions with (*>)+--   in the manner of 'traverse_' from "Data.Foldable". Any values returned by +--   reduced actions are discarded.+newtype Trav f = Trav { getTrav :: f () } ++instance Apply f => Semigroup (Trav f) where+  Trav a <> Trav b = Trav (a .> b)++instance Apply f => Reducer (f a) (Trav f) where+    unit = Trav . void+    a `cons` Trav b = Trav (a .> b)+    Trav a `snoc` b = Trav (void (a .> b))++-- | Efficiently avoid needlessly rebinding when using 'snoc' on an action that already returns ()+--   A rewrite rule automatically applies this when possible+snocTrav :: Reducer (f ()) (Trav f) => Trav f -> f () -> Trav f+snocTrav a = (<>) a . Trav+{-# RULES "unitTrav" unit = Trav #-}+{-# RULES "snocTrav" snoc = snocTrav #-}++-- | A 'App' turns any 'Apply' wrapped around a 'Semigroup' into a 'Semigroup'++newtype App f m = App { getApp :: f m } +  deriving (Functor,Apply)++instance (Apply f, Semigroup m) => Semigroup (App f m) where+  (<>) = liftF2 (<>)++instance (Apply f, Reducer c m) => Reducer (f c) (App f m) where+  unit = fmap unit . App
+ Data/Semigroup/Generator.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE UndecidableInstances, TypeOperators, FlexibleContexts, MultiParamTypeClasses, FlexibleInstances, TypeFamilies, CPP #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Semigroup.Generator+-- Copyright   :  (c) Edward Kmett 2009+-- License     :  BSD-style+-- Maintainer  :  ekmett@gmail.com+-- Stability   :  experimental+-- Portability :  portable+--+-- A 'Generator1' @c@ is a possibly-specialized container, which contains values of +-- type 'Elem' @c@, and which knows how to efficiently apply a 'Reducer' to extract+-- an answer.+--+-- 'Generator1' is to 'Generator' as 'Foldable1' is to 'Foldable'.+-----------------------------------------------------------------------------++module Data.Semigroup.Generator+  (+  -- * Generators+    Generator1(..)+  -- * Combinators+  , reduce1+  , mapReduceWith1+  , reduceWith1+  ) where++-- import Data.Monoid (Monoid(..))+-- import Data.Foldable (fold,foldMap)+import Data.List.NonEmpty+import Data.Semigroup (Semigroup(..)) -- , WrappedMonoid(..))+import Data.Semigroup.Foldable+import Data.Semigroup.Reducer+import Data.Generator++-- | minimal definition 'mapReduce1' or 'mapTo1'+class Generator c => Generator1 c where+  mapReduce1 :: Reducer e m => (Elem c -> e) -> c -> m+  mapTo1     :: Reducer e m => (Elem c -> e) -> m -> c -> m +  mapFrom1   :: Reducer e m => (Elem c -> e) -> c -> m -> m++  mapTo1 f m = (<>) m . mapReduce1 f+  mapFrom1 f = (<>) . mapReduce1 f++instance Generator1 (NonEmpty e) where+  mapReduce1 f = foldMap1 (unit . f)++{-+mapReduceDefault :: (Generator1 c, Reducer (Elem c) m, Monoid m) => (Elem c -> e) -> c -> m+mapReduceDefault f = unwrapMonoid . mapReduce1 f ++mapToDefault :: (Generator1 c, Reducer (Elem c) m, Monoid m) => (Elem c -> e) -> m -> c -> m+mapToDefault f = unwrapMonoid . mapTo1 f ++mapFromDefault :: (Generator1 c, Reducer (Elem c) m, Monoid m) => (Elem c -> e) -> m -> c -> m+mapFromDefault f = unwrapMonoid . mapFrom1 f +-}++-- | Apply a 'Reducer' directly to the elements of a 'Generator'+reduce1 :: (Generator1 c, Reducer (Elem c) m) => c -> m+reduce1 = mapReduce1 id+{-# SPECIALIZE reduce1 :: Reducer a m => NonEmpty a -> m #-}++mapReduceWith1 :: (Generator1 c, Reducer e m) => (m -> n) -> (Elem c -> e) -> c -> n+mapReduceWith1 f g = f . mapReduce1 g+{-# INLINE mapReduceWith1 #-}++reduceWith1 :: (Generator1 c, Reducer (Elem c) m) => (m -> n) -> c -> n+reduceWith1 f = f . reduce1+{-# INLINE reduceWith1 #-}
+ Data/Semigroup/Instances.hs view
@@ -0,0 +1,9 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+module Data.Semigroup.Instances where++import Data.FingerTree+import Data.Semigroup+import Data.Monoid++instance Measured v a => Semigroup (FingerTree v a) where+  (<>) = mappend
+ Data/Semigroup/Monad.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, GeneralizedNewtypeDeriving, FlexibleContexts, TypeOperators #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Semigroup.Monad+-- Copyright   :  (c) Edward Kmett 2009+-- License     :  BSD-style+-- Maintainer  :  ekmett@gmail.com+-- Stability   :  experimental+-- Portability :  non-portable (MPTCs)+--+-- Semigroups for working with 'Monad's.+--+-----------------------------------------------------------------------------++module Data.Semigroup.Monad+    ( Action(..)+    , Mon(..)+    ) where++import Control.Monad (liftM, liftM2)+import Data.Monoid (Monoid(..))+import Data.Semigroup (Semigroup(..))+import Data.Semigroup.Reducer (Reducer(..))++-- | A 'Action' uses an glues together monadic actions with (>>)+--   in the manner of 'mapM_' from "Data.Foldable". Any values returned by +--   reduced actions are discarded.+newtype Action f = Action { getAction :: f () } ++instance Monad f => Semigroup (Action f) where+  Action a <> Action b = Action (a >> b)++instance Monad f => Monoid (Action f) where+  mempty = Action (return ())+  Action a `mappend` Action b = Action (a >> b)++instance Monad f => Reducer (f a) (Action f) where+  unit a            = Action (a >> return ())+  a `cons` Action b = Action (a >> b)+  Action a `snoc` b = Action (a >> b >> return ())++-- | Efficiently avoid needlessly rebinding when using 'snoc' on an action that already returns ()+--   A rewrite rule automatically applies this when possible+snocAction :: Reducer (f ()) (Action f) => Action f -> f () -> Action f+snocAction a = (<>) a . Action+{-# RULES "unitAction" unit = Action #-}+{-# RULES "snocAction" snoc = snocAction #-}++newtype Mon f m = Mon { getMon :: f m } +  deriving (Monad)++instance (Monad f, Semigroup m) => Semigroup (Mon f m) where+  (<>) = liftM2 (<>)++instance (Monad f, Monoid m) => Monoid (Mon f m) where+  mempty = return mempty+  mappend = liftM2 mappend++instance (Monad f, Reducer c m) => Reducer (f c) (Mon f m) where+  unit = liftM unit . Mon
+ Data/Semigroup/MonadPlus.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, GeneralizedNewtypeDeriving, FlexibleContexts, TypeOperators #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Semigroup.MonadPlus+-- Copyright   :  (c) Edward Kmett 2009-2011+-- License     :  BSD-style+-- Maintainer  :  ekmett@gmail.com+-- Stability   :  experimental+-- Portability :  non-portable (MPTCs)+--+-- A semigroup for working with instances of 'MonadPlus'+--+-----------------------------------------------------------------------------++module Data.Semigroup.MonadPlus+    ( MonadSum(..)+    ) where++import Control.Monad (MonadPlus(..))+import Data.Monoid (Monoid(..))+import Data.Semigroup (Semigroup(..))+import Data.Semigroup.Reducer (Reducer(..))++-- | A 'MonadSum' turns any 'MonadPlus' instance into a 'Monoid'.++newtype MonadSum f a = MonadSum { getMonadSum :: f a } +  deriving (Monad,MonadPlus)++instance MonadPlus f => Semigroup (MonadSum f a) where+  MonadSum a <> MonadSum b = MonadSum (mplus a b)+   +instance MonadPlus f => Monoid (MonadSum f a) where+  mempty = mzero+  MonadSum a `mappend` MonadSum b = MonadSum (mplus a b) ++instance MonadPlus f => Reducer (f a) (MonadSum f a) where+  unit = MonadSum +
+ Data/Semigroup/Reducer.hs view
@@ -0,0 +1,192 @@+{-# LANGUAGE UndecidableInstances , FlexibleContexts , MultiParamTypeClasses , FlexibleInstances , GeneralizedNewtypeDeriving, TypeOperators, ScopedTypeVariables, CPP #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Semigroup.Reducer+-- Copyright   :  (c) Edward Kmett 2009+-- License     :  BSD3+-- Maintainer  :  ekmett@gmail.com+-- Stability   :  experimental+-- Portability :  non-portable (MPTCs)+--+-- A @c@-'Reducer' is a 'Semigroup' with a canonical mapping from @c@ to the Semigroup.+--+-----------------------------------------------------------------------------++module Data.Semigroup.Reducer+    ( Reducer+    , unit, snoc, cons+    , foldMapReduce, foldMapReduce1+    , foldReduce, foldReduce1+    , pureUnit+    , returnUnit+    ) where++import Control.Applicative++import Data.Monoid as Monoid+import Data.Semigroup as Semigroup+import Data.Semigroup.Foldable+import Data.Semigroup.Instances ()+import Data.Foldable+import Data.FingerTree++import qualified Data.Sequence as Seq+import Data.Sequence (Seq)+import qualified Data.Set as Set+import Data.Set (Set)+import qualified Data.IntSet as IntSet+import Data.IntSet (IntSet)+import qualified Data.IntMap as IntMap+import Data.IntMap (IntMap)+import qualified Data.Map as Map+import Data.Map (Map)++--import Text.Parsec.Prim++-- | This type may be best read infix. A @c `Reducer` m@ is a 'Semigroup' @m@ that maps+-- values of type @c@ through @unit@ to values of type @m@. A @c@-'Reducer' may also+-- supply operations which tack-on another @c@ to an existing 'Monoid' @m@ on the left+-- or right. These specialized reductions may be more efficient in some scenarios+-- and are used when appropriate by a 'Generator'. The names 'cons' and 'snoc' work+-- by analogy to the synonymous operations in the list monoid.+--+-- This class deliberately avoids functional-dependencies, so that () can be a @c@-Reducer+-- for all @c@, and so many common reducers can work over multiple types, for instance,+-- First and Last may reduce both @a@ and 'Maybe' @a@. Since a 'Generator' has a fixed element+-- type, the input to the reducer is generally known and extracting from the monoid usually+-- is sufficient to fix the result type. Combinators are available for most scenarios where+-- this is not the case, and the few remaining cases can be handled by using an explicit +-- type annotation.+--+-- Minimal definition: 'unit' or 'snoc'+class Semigroup m => Reducer c m where+  -- | Convert a value into a 'Semigroup'+  unit :: c -> m +  -- | Append a value to a 'Semigroup' for use in left-to-right reduction+  snoc :: m -> c -> m+  -- | Prepend a value onto a 'Semigroup' for use during right-to-left reduction+  cons :: c -> m -> m ++  snoc m = (<>) m . unit+  cons = (<>) . unit++-- | Apply a 'Reducer' to a 'Foldable' container, after mapping the contents into a suitable form for reduction.+foldMapReduce :: (Foldable f, Monoid m, Reducer e m) => (a -> e) -> f a -> m+foldMapReduce f = foldMap (unit . f)++foldMapReduce1 :: (Foldable1 f, Reducer e m) => (a -> e) -> f a -> m+foldMapReduce1 f = foldMap1 (unit . f)++-- | Apply a 'Reducer' to a 'Foldable' mapping each element through 'unit'+foldReduce :: (Foldable f, Monoid m, Reducer e m) => f e -> m+foldReduce = foldMap unit++-- | Apply a 'Reducer' to a 'Foldable1' mapping each element through 'unit'+foldReduce1 :: (Foldable1 f, Reducer e m) => f e -> m+foldReduce1 = foldMap1 unit++returnUnit :: (Monad m, Reducer c n) => c -> m n +returnUnit = return . unit++pureUnit :: (Applicative f, Reducer c n) => c -> f n+pureUnit = pure . unit++instance (Reducer c m, Reducer c n) => Reducer c (m,n) where+  unit x = (unit x,unit x)+  (m,n) `snoc` x = (m `snoc` x, n `snoc` x)+  x `cons` (m,n) = (x `cons` m, x `cons` n)++instance (Reducer c m, Reducer c n, Reducer c o) => Reducer c (m,n,o) where+  unit x = (unit x,unit x, unit x)+  (m,n,o) `snoc` x = (m `snoc` x, n `snoc` x, o `snoc` x)+  x `cons` (m,n,o) = (x `cons` m, x `cons` n, x `cons` o)++instance (Reducer c m, Reducer c n, Reducer c o, Reducer c p) => Reducer c (m,n,o,p) where+  unit x = (unit x,unit x, unit x, unit x)+  (m,n,o,p) `snoc` x = (m `snoc` x, n `snoc` x, o `snoc` x, p `snoc` x)+  x `cons` (m,n,o,p) = (x `cons` m, x `cons` n, x `cons` o, x `cons` p)++instance Reducer c [c] where+  unit = return+  cons = (:)+  xs `snoc` x = xs ++ [x]++instance Reducer c () where+  unit _ = ()+  _ `snoc` _ = ()+  _ `cons` _ = ()++instance Reducer Bool Any where+  unit = Any++instance Reducer Bool All where+  unit = All++instance Reducer (a -> a) (Endo a) where+  unit = Endo++instance Semigroup a => Reducer a (Dual a) where+  unit = Dual+    +instance Num a => Reducer a (Sum a) where+  unit = Sum++instance Num a => Reducer a (Product a) where+  unit = Product++instance Ord a => Reducer a (Min a) where+  unit = Min++instance Ord a => Reducer a (Max a) where+  unit = Max++instance Reducer (Maybe a) (Monoid.First a) where+  unit = Monoid.First++instance Reducer a (Semigroup.First a) where+  unit = Semigroup.First++instance Reducer (Maybe a) (Monoid.Last a) where+  unit = Monoid.Last++instance Reducer a (Semigroup.Last a) where+  unit = Semigroup.Last++instance Measured v a => Reducer a (FingerTree v a) where+  unit = singleton+  cons = (<|)+  snoc = (|>) ++--instance (Stream s m t, Reducer c a) => Reducer c (ParsecT s u m a) where+--    unit = return . unit++instance Reducer a (Seq a) where+  unit = Seq.singleton+  cons = (Seq.<|)+  snoc = (Seq.|>)++instance Reducer Int IntSet where+  unit = IntSet.singleton+  cons = IntSet.insert+  snoc = flip IntSet.insert -- left bias irrelevant++instance Ord a => Reducer a (Set a) where+  unit = Set.singleton+  cons = Set.insert+  -- pedantic about order in case 'Eq' doesn't implement structural equality+  snoc s m | Set.member m s = s +           | otherwise = Set.insert m s++instance Reducer (Int, v) (IntMap v) where+  unit = uncurry IntMap.singleton+  cons = uncurry IntMap.insert+  snoc = flip . uncurry . IntMap.insertWith $ const id++instance Ord k => Reducer (k, v) (Map k v) where+  unit = uncurry Map.singleton+  cons = uncurry Map.insert+  snoc = flip . uncurry . Map.insertWith $ const id++instance Monoid m => Reducer m (WrappedMonoid m) where+  unit = WrapMonoid
+ Data/Semigroup/Reducer/With.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE UndecidableInstances, FlexibleContexts, MultiParamTypeClasses, FlexibleInstances #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Semigroup.Reducer.With+-- Copyright   :  (c) Edward Kmett 2009-2011+-- License     :  BSD-style+-- Maintainer  :  ekmett@gmail.com+-- Stability   :  experimental+-- Portability :  non-portable (MPTCs)+--+-----------------------------------------------------------------------------++module Data.Semigroup.Reducer.With+    ( WithReducer(..)+    ) where++import Control.Applicative+import Data.FingerTree+import Data.Foldable+import Data.Traversable+import Data.Monoid+import Data.Semigroup.Reducer+import Data.Semigroup.Foldable+import Data.Semigroup.Traversable+import Data.Semigroup.Instances ()++-- | If @m@ is a @c@-"Reducer", then m is @(c `WithReducer` m)@-"Reducer"+--   This can be used to quickly select a "Reducer" for use as a 'FingerTree'+--   'measure'.++newtype WithReducer m c = WithReducer { withoutReducer :: c } +  deriving (Eq, Ord, Show, Read)++instance Functor (WithReducer m) where+  fmap f = WithReducer . f . withoutReducer++instance Foldable (WithReducer m) where+  foldMap f = f . withoutReducer++instance Traversable (WithReducer m) where+  traverse f (WithReducer a) = WithReducer <$> f a++instance Foldable1 (WithReducer m) where+  foldMap1 f = f . withoutReducer++instance Traversable1 (WithReducer m) where+  traverse1 f (WithReducer a) = WithReducer <$> f a++instance Reducer c m => Reducer (WithReducer m c) m where+    unit = unit . withoutReducer ++instance (Monoid m, Reducer c m) => Measured m (WithReducer m c) where+    measure = unit . withoutReducer
+ Data/Semigroup/Self.hs view
@@ -0,0 +1,52 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, GeneralizedNewtypeDeriving #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Semigroup.Self+-- Copyright   :  (c) Edward Kmett 2009+-- License     :  BSD-style+-- Maintainer  :  ekmett@gmail.com+-- Stability   :  experimental+-- Portability :  portable+--+-- A simple 'Monoid' transformer that takes a 'Monoid' m and produces a new @m@-Reducer named 'Self' @m@+-- +-- This is useful when you have a generator that already contains monoidal values or someone supplies+-- the map to the monoid in the form of a function rather than as a "Reducer" instance. You can just+-- @'getSelf' . `reduce`@ or @'getSelf' . 'mapReduce' f@ in those scenarios. These behaviors are encapsulated +-- into the 'fold' and 'foldMap' combinators in "Data.Monoid.Combinators" respectively.+--+-----------------------------------------------------------------------------++module Data.Semigroup.Self+    ( Self(..)+    )  where++import Control.Applicative+import Data.Monoid (Monoid(..))+import Data.Foldable+import Data.Traversable+import Data.Semigroup+import Data.Semigroup.Foldable+import Data.Semigroup.Traversable+import Data.Semigroup.Reducer (Reducer(..))++newtype Self m = Self { getSelf :: m } deriving (Semigroup, Monoid)++instance Semigroup m => Reducer m (Self m) where+  unit = Self++instance Functor Self where+  fmap f (Self x) = Self (f x)++instance Foldable Self where+  foldMap f (Self x) = f x++instance Traversable Self where+  traverse f (Self x) = Self <$> f x++instance Foldable1 Self where+  foldMap1 f (Self x) = f x++instance Traversable1 Self where+  traverse1 f (Self x) = Self <$> f x
+ Data/Semigroup/Union.hs view
@@ -0,0 +1,175 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, GeneralizedNewtypeDeriving #-}+module Data.Semigroup.Union+    ( module Data.Semigroup.Reducer+    -- * Unions of Containers+    , HasUnion+    , empty+    , union+    , Union(Union,getUnion)+    -- * Unions of Containers of Semigroups+    , HasUnionWith+    , emptyWith+    , unionWith+    , UnionWith(UnionWith,getUnionWith)+    ) where++import qualified Data.HashMap.Lazy as HashMap+import Data.HashMap.Lazy (HashMap)++import qualified Data.IntMap as IntMap+import Data.IntMap (IntMap)++import qualified Data.IntSet as IntSet+import Data.IntSet (IntSet)++import qualified Data.HashSet as HashSet+import Data.HashSet (HashSet)++import qualified Data.Map as Map+import Data.Map (Map)++import qualified Data.Set as Set+import Data.Set (Set)++import qualified Data.List as List++import Data.Hashable+import Data.Functor+import Data.Foldable+import Data.Traversable+import Data.Monoid+import Data.Semigroup+import Data.Semigroup.Foldable+import Data.Semigroup.Traversable+import Data.Semigroup.Reducer+import Data.Semigroup.Instances ()++-- | A Container suitable for the 'Union' 'Monoid'+class HasUnion f where+  {-# SPECIALIZE union :: IntMap a -> IntMap a -> IntMap a #-}+  {-# SPECIALIZE union :: Ord k => Map k a -> Map k a -> Map k a #-}+  {-# SPECIALIZE union :: Eq a => [a] -> [a] -> [a] #-}+  {-# SPECIALIZE union :: Ord a => Set a -> Set a -> Set a #-}+  {-# SPECIALIZE union :: IntSet -> IntSet -> IntSet #-}+  {-# SPECIALIZE union :: Eq a => HashSet a -> HashSet a -> HashSet a #-}+  {-# SPECIALIZE union :: Eq k => HashMap k a -> HashMap k a -> HashMap k a #-}+  union :: f -> f -> f++class HasUnion f => HasUnion0 f where+  empty :: f++instance HasUnion (IntMap a) where+  union = IntMap.union++instance HasUnion0 (IntMap a) where+  empty = IntMap.empty++instance Eq k => HasUnion (HashMap k a) where+  union = HashMap.union++instance Eq k => HasUnion0 (HashMap k a) where+  empty = HashMap.empty++instance Ord k => HasUnion (Map k a) where+  union = Map.union++instance Ord k => HasUnion0 (Map k a) where+  empty = Map.empty++instance Eq a => HasUnion [a] where+  union = List.union++instance Eq a => HasUnion0 [a] where+  empty = []++instance Ord a => HasUnion (Set a) where+  union = Set.union++instance Ord a => HasUnion0 (Set a) where+  empty = Set.empty++instance HasUnion IntSet where+  union = IntSet.union++instance HasUnion0 IntSet where+  empty = IntSet.empty++instance (Eq a, Hashable a) => HasUnion (HashSet a) where+  union = HashSet.union++instance (Eq a, Hashable a) => HasUnion0 (HashSet a) where+  empty = HashSet.empty+++-- | The 'Monoid' @('union','empty')@+newtype Union f = Union { getUnion :: f } +  deriving (Eq,Ord,Show,Read)++instance HasUnion f => Semigroup (Union f) where+  Union a <> Union b = Union (a `union` b)++instance HasUnion0 f => Monoid (Union f) where+  Union a `mappend` Union b = Union (a `union` b)+  mempty = Union empty++instance HasUnion f => Reducer f (Union f) where+  unit = Union++instance Functor Union where+  fmap f (Union a) = Union (f a)++instance Foldable Union where+ foldMap f (Union a) = f a++instance Traversable Union where+  traverse f (Union a) = Union <$> f a++instance Foldable1 Union where+  foldMap1 f (Union a) = f a++instance Traversable1 Union where+  traverse1 f (Union a) = Union <$> f a++-- | Polymorphic containers that we can supply an operation to handle unions with+class Functor f => HasUnionWith f where+  {-# SPECIALIZE unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a #-}+  {-# SPECIALIZE unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a #-}+  {-# SPECIALIZE unionWith :: Eq k => (a -> a -> a) -> HashMap k a -> HashMap k a -> HashMap k a #-}+  unionWith :: (a -> a -> a) -> f a -> f a -> f a++class HasUnionWith f => HasUnionWith0 f where+  emptyWith :: f a ++instance HasUnionWith IntMap where +  unionWith = IntMap.unionWith++instance HasUnionWith0 IntMap where +  emptyWith = IntMap.empty++instance Ord k => HasUnionWith (Map k) where +  unionWith = Map.unionWith++instance Ord k => HasUnionWith0 (Map k) where +  emptyWith = Map.empty++-- TODO: add unionWith to unordered-containers++--instance Eq k => HasUnionWith (HashMap k) where +--  unionWith = HashMap.unionWith++--instance Ord k => HasUnionWith0 (Map k) where +--  emptyWith = Map.empty++-- | The 'Monoid' @('unionWith mappend','empty')@ for containers full of monoids.+newtype UnionWith f m = UnionWith { getUnionWith :: f m } ++instance (HasUnionWith f, Semigroup m) => Semigroup (UnionWith f m) where+    UnionWith a <> UnionWith b = UnionWith (unionWith (<>) a b)++instance (HasUnionWith0 f, Monoid m) => Monoid (UnionWith f m) where+    mempty = UnionWith emptyWith+    UnionWith a `mappend` UnionWith b = UnionWith (unionWith mappend a b)++instance (HasUnionWith f, Semigroup m, Monoid m) => Reducer (f m) (UnionWith f m) where+    unit = UnionWith+
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright 2008-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
+ reducers.cabal view
@@ -0,0 +1,51 @@+name:          reducers+category:      Data, Math, Numerical, Semigroups+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/reducers/+copyright:     Copyright (C) 2008-2011 Edward A. Kmett+synopsis:      Semigroups, specialized containers and a general map/reduce framework+description:   Semigroups, specialized containers and a general map/reduce framework+build-type:    Simple++source-repository head+  type: git+  location: git://github.com/ekmett/reducers.git++library+  build-depends: +    base                   >= 4        && < 5,+    array                  >= 0.3      && < 0.4,+    transformers           >= 0.2      && < 0.3,+    bytestring             >= 0.9.1    && < 0.10,+    containers             >= 0.3      && < 0.5,+    fingertree             >= 0.0.1    && < 0.1,+    hashable               >= 1.1.2.1  && < 1.2,+    text                   >= 0.11.1.5 && < 0.12,+    parallel               >= 3.1      && < 3.2,+    unordered-containers   >= 0.1.4    && < 0.2,+    semigroups             >= 0.7.1    && < 0.8,+    semigroupoids          >= 1.2.2.4  && < 1.3++  exposed-modules:+    Data.Generator+    Data.Generator.Combinators+    Data.Semigroup.Generator+    Data.Semigroup.Reducer+    Data.Semigroup.Reducer.With+    Data.Semigroup.Instances+    Data.Semigroup.Union+    Data.Semigroup.Apply+    Data.Semigroup.Applicative+    Data.Semigroup.Alt+    Data.Semigroup.Alternative+    Data.Semigroup.Monad+    Data.Semigroup.MonadPlus+    Data.Semigroup.Self++  ghc-options: -Wall