monoids 0.1.21 → 0.1.25
raw patch · 30 files changed
+1048/−799 lines, 30 files
Files
- Data/Field.hs +29/−0
- Data/Field/VectorSpace.hs +11/−0
- Data/Generator.hs +186/−0
- Data/Generator/Combinators.hs +223/−0
- Data/Generator/Compressive/LZ78.hs +114/−0
- Data/Generator/Compressive/RLE.hs +101/−0
- Data/Generator/Free.hs +114/−0
- Data/Group.hs +6/−0
- Data/Group/Multiplicative.hs +56/−0
- Data/Group/Multiplicative/Sugar.hs +41/−0
- Data/Monoid/Applicative.hs +2/−2
- Data/Monoid/Combinators.hs +11/−207
- Data/Monoid/FromString.hs +1/−1
- Data/Monoid/Generator.hs +0/−186
- Data/Monoid/Generator/Free.hs +0/−114
- Data/Monoid/Generator/LZ78.hs +0/−114
- Data/Monoid/Generator/RLE.hs +0/−100
- Data/Monoid/Lexical/SourcePosition.hs +1/−1
- Data/Monoid/Lexical/Words.hs +1/−1
- Data/Monoid/Monad.hs +2/−2
- Data/Monoid/Multiplicative.hs +12/−7
- Data/Monoid/Reducer.hs +13/−1
- Data/Monoid/Self.hs +1/−1
- Data/Ring.hs +7/−3
- Data/Ring/Algebra.hs +13/−0
- Data/Ring/Module/AutomaticDifferentiation.hs +56/−30
- Data/Ring/Semi.hs +8/−0
- Data/Ring/Semi/Natural.hs +2/−2
- Data/Ring/Semi/Near.hs +25/−21
- monoids.cabal +12/−6
+ Data/Field.hs view
@@ -0,0 +1,29 @@+-----------------------------------------------------------------------------+-- |+-- Module : Data.Field+-- Copyright : (c) Edward Kmett 2009+-- License : BSD-style+-- Maintainer : ekmett@gmail.com+-- Stability : experimental+-- Portability : portable+--+-----------------------------------------------------------------------------++module Data.Field+ ( module Data.Group.Multiplicative+ , module Data.Ring+ , Field+ ) where++import Data.Group.Multiplicative+import Data.Ring+import Data.Monoid.Self+import Data.Monoid.FromString+import Data.Monoid.Reducer++class (Ring a, MultiplicativeGroup a) => Field a++instance Field f => Field (Dual f)+instance Field f => Field (Self f)+instance Field f => Field (FromString f)+instance Field f => Field (ReducedBy f s)
+ Data/Field/VectorSpace.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}+module Data.Field.VectorSpace + ( module Data.Field+ , module Data.Ring.Module+ , VectorSpace+ ) where++import Data.Field+import Data.Ring.Module+ +class (Field f, Module f g) => VectorSpace f g
+ Data/Generator.hs view
@@ -0,0 +1,186 @@+{-# LANGUAGE UndecidableInstances, TypeOperators, FlexibleContexts, MultiParamTypeClasses, FlexibleInstances, TypeFamilies #-}++-----------------------------------------------------------------------------+-- |+-- 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+ ( module Data.Monoid.Reducer+ -- * Generators+ , Generator+ , Elem+ , mapReduce+ , mapTo+ , mapFrom+ -- * Generator Transformers+ , Keys(Keys, getKeys)+ , Values(Values, getValues)+ , Char8(Char8, getChar8)+ -- * Combinators+ , reduce+ , mapReduceWith+ , reduceWith+ ) where++import Data.Array +import Data.Word (Word8)+import Data.Text (Text)+import Data.Foldable (fold,foldMap)+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 qualified Data.Sequence as Seq+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.Map as Map+import Data.Map (Map)++import Control.Parallel.Strategies+import Data.Monoid.Reducer++-- | minimal definition 'mapReduce' or 'mapTo'+class Generator c where+ type Elem c :: * + mapReduce :: (e `Reducer` m) => (Elem c -> e) -> c -> m+ mapTo :: (e `Reducer` m) => (Elem c -> e) -> m -> c -> m + mapFrom :: (e `Reducer` 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 rwhnf (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 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 (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 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 rwhnf (mapReduce f . Char8) . Lazy8.toChunks . getChar8++-- | Apply a 'Reducer' directly to the elements of a 'Generator'+reduce :: (Generator c, Elem c `Reducer` m) => c -> m+reduce = mapReduce id+{-# SPECIALIZE reduce :: (Word8 `Reducer` m) => Strict.ByteString -> m #-}+{-# SPECIALIZE reduce :: (Word8 `Reducer` m) => Lazy.ByteString -> m #-}+{-# SPECIALIZE reduce :: (Char `Reducer` m) => Char8 Strict.ByteString -> m #-}+{-# SPECIALIZE reduce :: (Char `Reducer` m) => Char8 Lazy.ByteString -> m #-}+{-# SPECIALIZE reduce :: (c `Reducer` m) => [c] -> m #-}+{-# SPECIALIZE reduce :: (Generator (FingerTree v e), e `Reducer` m) => FingerTree v e -> m #-}+{-# SPECIALIZE reduce :: (Char `Reducer` m) => Text -> m #-}+{-# SPECIALIZE reduce :: (e `Reducer` m) => Seq e -> m #-}+{-# SPECIALIZE reduce :: (Int `Reducer` m) => IntSet -> m #-}+{-# SPECIALIZE reduce :: (a `Reducer` m) => Set a -> m #-}+{-# SPECIALIZE reduce :: ((Int,v) `Reducer` m) => IntMap v -> m #-}+{-# SPECIALIZE reduce :: ((k,v) `Reducer` m) => Map k v -> m #-}+{-# SPECIALIZE reduce :: (Int `Reducer` m) => Keys (IntMap v) -> m #-}+{-# SPECIALIZE reduce :: (k `Reducer` m) => Keys (Map k v) -> m #-}+{-# SPECIALIZE reduce :: (v `Reducer` m) => Values (IntMap v) -> m #-}+{-# SPECIALIZE reduce :: (v `Reducer` m) => Values (Map k v) -> m #-}++mapReduceWith :: (Generator c, e `Reducer` m) => (m -> n) -> (Elem c -> e) -> c -> n+mapReduceWith f g = f . mapReduce g+{-# INLINE mapReduceWith #-}++reduceWith :: (Generator c, Elem c `Reducer` m) => (m -> n) -> c -> n+reduceWith f = f . reduce+{-# INLINE reduceWith #-}
+ Data/Generator/Combinators.hs view
@@ -0,0 +1,223 @@+{-# 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+ ( module Data.Generator+ -- * 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, elem, filter, concatMap, and, or, all, sum, product, notElem, replicate, cycle, repeat)+import Control.Applicative+import Control.Monad (MonadPlus)+import Data.Generator+import Data.Monoid.Applicative+import Data.Monoid.Self+import Data.Monoid.Monad++-- | 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 getAlt+{-# 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 'Self' monoid. A specialized version of its namesake from "Data.Foldable"+--+-- @+-- 'mapReduceWith' 'getSelf'+-- @+foldMap :: (Monoid m, Generator c) => (Elem c -> m) -> c -> m+foldMap = mapReduceWith getSelf+{-# 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 'Self' monoid. A specialized version of its namesake from "Data.Foldable"+--+-- @+-- 'reduceWith' 'getSelf'+-- @+fold :: (Monoid m, Generator c, Elem c ~ m) => c -> m+fold = reduceWith getSelf+{-# 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, Elem c `Reducer` 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, Elem c `Reducer` 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/Generator/Compressive/LZ78.hs view
@@ -0,0 +1,114 @@+{-# LANGUAGE TypeFamilies, MultiParamTypeClasses #-}++-----------------------------------------------------------------------------+-- |+-- Module : Data.Generator.Compressive.LZ78+-- Copyright : (c) Edward Kmett 2009+-- License : BSD-style+-- Maintainer : ekmett@gmail.com+-- Stability : experimental+-- Portability : portable+--+-- Compression algorithms are all about exploiting redundancy. When applying+-- an expensive 'Reducer' to a redundant source, it may be better to +-- extract the structural redundancy that is present. 'LZ78' is a compression+-- algorithm that does so, without requiring the dictionary to be populated+-- with all of the possible values of a data type unlike its later +-- refinement LZW, and which has fewer comparison reqirements during encoding+-- than its earlier counterpart LZ77. Since we aren't storing these as a +-- bitstream the LZSS refinement of only encoding pointers once you cross+-- the break-even point is a net loss. +-----------------------------------------------------------------------------+++module Data.Generator.Compressive.LZ78 + ( module Data.Generator+ -- * Lempel-Ziv 78 + , LZ78+ -- * Decoding+ , decode+ -- * Encoding+ , encode+ , encodeEq+ -- * QuickCheck Properties+ , prop_decode_encode+ , prop_decode_encodeEq+ ) where++import qualified Data.Sequence as Seq+import Data.Sequence (Seq,(|>))+import qualified Data.Map as Map+import Data.Map (Map)+import qualified Data.List as List+import Data.Generator+import Data.Foldable+import Data.Monoid.Self++-- | An LZ78 compressing 'Generator', which supports efficient 'mapReduce' operations++data Token a = Token a {-# UNPACK #-} !Int + deriving (Eq,Ord,Show,Read)++-- after using the Functor instance the encoding may no longer be minimal+instance Functor Token where+ fmap f (Token a n) = Token (f a) n++newtype LZ78 a = LZ78 { getLZ78 :: [Token a] } + deriving (Eq,Ord,Show)++emptyDict :: Monoid m => Seq m+emptyDict = Seq.singleton mempty++instance Generator (LZ78 a) where+ type Elem (LZ78 a) = a+ mapTo f m (LZ78 xs) = mapTo' f m emptyDict xs++instance Functor LZ78 where+ fmap f = LZ78 . fmap (fmap f) . getLZ78++instance Foldable LZ78 where+ foldMap f = getSelf . mapReduce f+ fold = getSelf . reduce+ +mapTo' :: (e `Reducer` m) => (a -> e) -> m -> Seq m -> [Token a] -> m+mapTo' _ m _ [] = m+mapTo' f m s (Token c w:ws) = m `mappend` mapTo' f v (s |> v) ws + where + v = Seq.index s w `mappend` unit (f c)++-- | a type-constrained 'reduce' operation+ +decode :: LZ78 a -> [a]+decode = reduce++-- | contruct an LZ78-compressed 'Generator' using a 'Map' internally, requires an instance of Ord.++encode :: Ord a => [a] -> LZ78 a+encode = LZ78 . encode' Map.empty 1 0++encode' :: Ord a => Map (Token a) Int -> Int -> Int -> [a] -> [Token a]+encode' _ _ p [c] = [Token c p]+encode' d f p (c:cs) = let t = Token c p in case Map.lookup t d of+ Just p' -> encode' d f p' cs+ Nothing -> t : encode' (Map.insert t f d) (succ f) 0 cs+encode' _ _ _ [] = []++-- | contruct an LZ78-compressed 'Generator' using a list internally, requires an instance of Eq.++encodeEq :: Eq a => [a] -> LZ78 a+encodeEq = LZ78 . encodeEq' [] 1 0++encodeEq' :: Eq a => [(Token a,Int)] -> Int -> Int -> [a] -> [Token a]+encodeEq' _ _ p [c] = [Token c p]+encodeEq' d f p (c:cs) = let t = Token c p in case List.lookup t d of+ Just p' -> encodeEq' d f p' cs+ Nothing -> t : encodeEq' ((t,f):d) (succ f) 0 cs+encodeEq' _ _ _ [] = []++-- | QuickCheck property: decode . encode = id+prop_decode_encode :: Ord a => [a] -> Bool+prop_decode_encode xs = decode (encode xs) == xs++-- | QuickCheck property: decode . encodeEq = id+prop_decode_encodeEq :: Eq a => [a] -> Bool+prop_decode_encodeEq xs = decode (encodeEq xs) == xs
+ Data/Generator/Compressive/RLE.hs view
@@ -0,0 +1,101 @@+{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, TypeOperators, FlexibleInstances, FlexibleContexts #-}++-----------------------------------------------------------------------------+-- |+-- Module : Data.Generator.Compressive.RLE+-- Copyright : (c) Edward Kmett 2009+-- License : BSD-style+-- Maintainer : ekmett@gmail.com+-- Stability : experimental+-- Portability : portable+--+-- Compression algorithms are all about exploiting redundancy. When applying+-- an expensive 'Reducer' to a redundant source, it may be better to +-- extract the structural redundancy that is present. Run length encoding+-- can do so for long runs of identical inputs.+-----------------------------------------------------------------------------++module Data.Generator.Compressive.RLE+ ( module Data.Generator+ , RLE(RLE, getRLE)+ , Run(Run)+ , decode+ , encode+ , encodeList+ , prop_decode_encode+ , prop_decode_encodeList+ ) where++import qualified Data.Sequence as Seq+import Data.Sequence (Seq,(|>),(<|),ViewL(..),ViewR(..),(><),viewl,viewr)+import Data.Foldable+import Data.Generator+import qualified Data.Monoid.Combinators as Monoid +import Control.Functor.Pointed++-- | A single run with a strict length.+data Run a = Run a {-# UNPACK #-} !Int++instance Functor Run where+ fmap f (Run a n) = Run (f a) n++instance Pointed Run where+ point a = Run a 1++-- | A 'Generator' which supports efficient 'mapReduce' operations over run-length encoded data.+newtype RLE f a = RLE { getRLE :: f (Run a) } ++instance Functor f => Functor (RLE f) where+ fmap f = RLE . fmap (fmap f) . getRLE++instance Foldable f => Generator (RLE f a) where+ type Elem (RLE f a) = a+ mapReduce f = foldMap run . getRLE where+ run (Run a n) = unit (f a) `Monoid.replicate` n++decode :: Foldable f => RLE f a -> [a]+decode = reduce++-- | naive left to right encoder, which can handle infinite data++encodeList :: Eq a => [a] -> RLE [] a+encodeList [] = RLE []+encodeList (a:as) = RLE (point a `before` as)++before :: Eq a => Run a -> [a] -> [Run a]+r `before` [] = [r]+r@(Run a n) `before` (b:bs) | a == b = Run a (n+1) `before` bs+ | otherwise = r : point b `before` bs++-- | QuickCheck property: decode . encode = id+prop_decode_encodeList :: Eq a => [a] -> Bool+prop_decode_encodeList xs = decode (encode xs) == xs++-- One nice property that run-length encoding has is that it can be computed monoidally as follows+-- However, this monoid cannot be used to handle infinite sources.++instance Eq a => Monoid (RLE Seq a) where+ mempty = RLE Seq.empty+ RLE l `mappend` RLE r = viewr l `merge` viewl r where+ (l' :> Run a m) `merge` (Run b n :< r')+ | a == b = RLE ((l' |> Run a (m+n)) >< r')+ | otherwise = RLE (l >< r)+ EmptyR `merge` _ = RLE r+ _ `merge` EmptyL = RLE l++instance Eq a => Reducer a (RLE Seq a) where+ unit = RLE . Seq.singleton . point+ cons a (RLE r) = case viewl r of+ Run b n :< r' | a == b -> RLE (Run a (n+1) <| r')+ | otherwise -> RLE (Run a 1 <| r )+ EmptyL -> RLE (return (point a))+ snoc (RLE l) a = case viewr l of+ l' :> Run b n | a == b -> RLE (l' |> Run b (n+1))+ | otherwise -> RLE (l |> Run a 1 )+ EmptyR -> RLE (return (point a))++encode :: (Generator c, Eq (Elem c)) => c -> RLE Seq (Elem c)+encode = reduce++prop_decode_encode :: (Generator c, Eq (Elem c)) => c -> Bool+prop_decode_encode xs = decode (encode xs) == reduce xs
+ Data/Generator/Free.hs view
@@ -0,0 +1,114 @@+{-# LANGUAGE UndecidableInstances , FlexibleContexts , MultiParamTypeClasses , FlexibleInstances , GeneralizedNewtypeDeriving, ExistentialQuantification, TypeFamilies #-}++-----------------------------------------------------------------------------+-- |+-- Module : Data.Generator.Free+-- Copyright : (c) Edward Kmett 2009+-- License : BSD-style+-- Maintainer : ekmett@gmail.com+-- Stability : experimental+-- Portability : non-portable (MPTCs)+--+-----------------------------------------------------------------------------++module Data.Generator.Free+ ( module Data.Generator+ , module Data.Monoid.Reducer+ , Free (AnyGenerator)+ ) where++import Control.Functor.Pointed+import Control.Monad+import Data.Generator+import Data.Foldable+import Data.Monoid.Reducer+import Data.Monoid.Additive+import qualified Data.Generator.Combinators as Generator+import Data.Monoid.Self++data Free a + = a `Cons` Free a+ | Free a `Snoc` a+ | Free a `Plus` Free a+ | Unit a+ | Empty+ | forall c. (Generator c, Elem c ~ a) => AnyGenerator c++instance Eq a => Eq (Free a) where+ a == b = Generator.toList a == Generator.toList b+ a /= b = Generator.toList a == Generator.toList b++instance Ord a => Ord (Free a) where+ a <= b = Generator.toList a <= Generator.toList b+ a >= b = Generator.toList a >= Generator.toList b+ a < b = Generator.toList a < Generator.toList b+ a > b = Generator.toList a > Generator.toList b+ a `compare` b = Generator.toList a `compare` Generator.toList b++instance Monoid (Free a) where+ mempty = Empty+ mappend = Plus++instance Reducer a (Free a) where+ unit = Unit++ snoc Empty a = Unit a+ snoc a b = Snoc a b++ cons b Empty = Unit b+ cons a b = Cons a b ++instance Functor Free where+ fmap f (a `Cons` b) = f a `Cons` fmap f b+ fmap f (a `Snoc` b) = fmap f a `Snoc` f b+ fmap f (a `Plus` b) = fmap f a `Plus` fmap f b+ fmap f (Unit a) = Unit (f a)+ fmap _ Empty = Empty+ fmap f (AnyGenerator c) = mapReduce f c++instance Pointed Free where+ point = Unit++instance Monad Free where+ return = Unit+ a `Cons` b >>= k = k a `Plus` (b >>= k)+ a `Snoc` b >>= k = (a >>= k) `Plus` k b+ a `Plus` b >>= k = (a >>= k) `Plus` (b >>= k)+ Unit a >>= k = k a+ Empty >>= _ = Empty+ AnyGenerator c >>= k = getSelf (mapReduce k c)++instance MonadPlus Free where+ mzero = Empty+ mplus = Plus++instance Foldable Free where+ foldMap f (a `Cons` b) = f a `mappend` foldMap f b+ foldMap f (a `Snoc` b) = foldMap f a `mappend` f b+ foldMap f (a `Plus` b) = foldMap f a `mappend` foldMap f b+ foldMap f (Unit a) = f a + foldMap _ Empty = mempty+ foldMap f (AnyGenerator c) = Generator.foldMap f c++instance Generator (Free a) where+ type Elem (Free a) = a+ mapReduce f (a `Cons` b) = f a `cons` mapReduce f b+ mapReduce f (a `Snoc` b) = mapReduce f a `snoc` f b+ mapReduce f (a `Plus` b) = mapReduce f a `plus` mapReduce f b+ mapReduce f (Unit a) = unit (f a)+ mapReduce _ Empty = mempty+ mapReduce f (AnyGenerator c) = mapReduce f c+ + mapTo f m (a `Cons` b) = m `plus` (f a `cons` mapReduce f b)+ mapTo f m (a `Snoc` b) = mapTo f m a `snoc` f b+ mapTo f m (a `Plus` b) = mapTo f m a `plus` mapReduce f b+ mapTo f m (Unit a) = m `snoc` f a+ mapTo _ m Empty = m + mapTo f m (AnyGenerator c) = mapTo f m c+ + mapFrom f (a `Cons` b) m = f a `cons` mapFrom f b m + mapFrom f (a `Snoc` b) m = mapFrom f a (f b `cons` m)+ mapFrom f (a `Plus` b) m = mapReduce f a `plus` mapFrom f b m+ mapFrom f (Unit a) m = f a `cons` m+ mapFrom _ Empty m = m + mapFrom f (AnyGenerator c) m = mapFrom f c m
Data/Group.hs view
@@ -22,6 +22,7 @@ import Data.Monoid.Additive import Data.Monoid.Self import Data.Monoid.FromString+import Data.Monoid.Reducer infixl 6 `minus` @@ -54,3 +55,8 @@ instance Group a => Group (FromString a) where gnegate = FromString . gnegate . getFromString FromString a `minus` FromString b = FromString (a `minus` b)++instance Group a => Group (ReducedBy a s) where+ gnegate = Reduction . gnegate . getReduction+ Reduction a `minus` Reduction b = Reduction (a `minus` b)+
+ Data/Group/Multiplicative.hs view
@@ -0,0 +1,56 @@+-----------------------------------------------------------------------------+-- |+-- Module : Data.Group.Multiplicative+-- Copyright : (c) Edward Kmett 2009+-- License : BSD-style+-- Maintainer : ekmett@gmail.com+-- Stability : experimental+-- Portability : portable+--+-----------------------------------------------------------------------------++module Data.Group.Multiplicative + ( module Data.Monoid.Multiplicative+ , module Data.Group+ , MultiplicativeGroup+ , over+ , under+ , grecip+ ) where++import Data.Monoid.Multiplicative+import Data.Group+import Data.Monoid.Self+import Data.Monoid.FromString+import Data.Monoid.Reducer++ +-- | Minimal definition over or grecip+class Multiplicative g => MultiplicativeGroup g where+ -- | @x / y@+ over :: g -> g -> g+ -- | @x \ y@+ under :: g -> g -> g+ grecip :: g -> g++ x `under` y = grecip x `times` y+ x `over` y = x `times` grecip y+ grecip x = one `over` x++instance MultiplicativeGroup g => MultiplicativeGroup (Self g) where+ Self x `over` Self y = Self (x `over` y)+ Self x `under` Self y = Self (x `under` y)+ grecip (Self x) = Self (grecip x)++instance MultiplicativeGroup g => MultiplicativeGroup (FromString g) where+ FromString x `over` FromString y = FromString (x `over` y)+ FromString x `under` FromString y = FromString (x `under` y)+ grecip (FromString x) = FromString (grecip x)++instance MultiplicativeGroup g => MultiplicativeGroup (ReducedBy g s) where+ Reduction x `over` Reduction y = Reduction (x `over` y)+ Reduction x `under` Reduction y = Reduction (x `under` y)+ grecip (Reduction x) = Reduction (grecip x)++instance MultiplicativeGroup a => MultiplicativeGroup (Dual a) where+ grecip = Dual . grecip . getDual
+ Data/Group/Multiplicative/Sugar.hs view
@@ -0,0 +1,41 @@+-----------------------------------------------------------------------------+-- |+-- Module : Data.Group.Multiplicative.Sugar+-- Copyright : (c) Edward Kmett 2009+-- License : BSD-style+-- Maintainer : ekmett@gmail.com+-- Stability : experimental+-- Portability : portable+--+-- Syntactic sugar for working with groups that conflicts with names from the "Prelude".+--+-- > import Prelude hiding ((-), (+), (*), (/), negate, subtract, recip)+-- > import Data.Group.Multiplicative.Sugar+--+-----------------------------------------------------------------------------++module Data.Group.Multiplicative.Sugar + ( module Data.Monoid.Multiplicative.Sugar+ , module Data.Group.Multiplicative+ , module Data.Group.Sugar+ , (/)+ , (\\)+ , recip+ ) where++import Data.Group.Multiplicative+import Data.Monoid.Multiplicative.Sugar+import Data.Group.Sugar+import Prelude hiding ((-), (+), (*), (/), negate, subtract, recip)++infixl 7 /+infixr 7 \\++(/) :: MultiplicativeGroup g => g -> g -> g+(/) = over++(\\) :: MultiplicativeGroup g => g -> g -> g+(\\) = under++recip :: MultiplicativeGroup g => g -> g+recip = grecip
Data/Monoid/Applicative.hs view
@@ -53,7 +53,7 @@ -- | A 'Alt' turns any 'Alternative' instance into a 'Monoid'. -- It also provides a 'Multiplicative' instance for an 'Applicative' functor wrapped around a 'Monoid'--- and asserts that any 'Alternative' applied to a 'Monoid' forms a 'LeftSemiNearRing' +-- and asserts that any 'Alternative' applied to a 'Monoid' forms a 'RightSemiNearRing' -- under these operations. newtype Alt f a = Alt { getAlt :: f a } @@ -73,7 +73,7 @@ instance Alternative f => Reducer (f a) (Alt f a) where unit = Alt -instance (Alternative f, Monoid a) => LeftSemiNearRing (Alt f a)+instance (Alternative f, Monoid a) => RightSemiNearRing (Alt f a) -- | if @m@ is a 'Module' over @r@ and @f@ is a 'Applicative' then @f `App` m@ is a 'Module' over @r@ as well
Data/Monoid/Combinators.hs view
@@ -12,221 +12,33 @@ -- 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.Group.Combinators as Monoid +-- > import Data.Monoid.Combinators as Monoid -- ----------------------------------------------------------------------------- module Data.Monoid.Combinators- ( module Data.Monoid.Generator- -- * 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+ ( -- * List-Like Monoid Production- , repeat+ repeat , replicate , cycle -- * QuickCheck Properties , prop_replicate_right_distributive ) where -import Prelude hiding (mapM_, any, elem, filter, concatMap, and, or, all, sum, product, notElem, replicate, cycle, repeat)-import Control.Applicative+import Prelude hiding (replicate, cycle, repeat) import Control.Monad (MonadPlus)-import Data.Monoid.Generator-import Data.Monoid.Applicative-import Data.Monoid.Self-import Data.Monoid.Monad+import Data.Monoid.Reducer import Test.QuickCheck --- | 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 getAlt-{-# 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 'Self' monoid. A specialized version of its namesake from "Data.Foldable"------ @--- 'mapReduceWith' 'getSelf'--- @-foldMap :: (Monoid m, Generator c) => (Elem c -> m) -> c -> m-foldMap = mapReduceWith getSelf-{-# 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 'Self' monoid. A specialized version of its namesake from "Data.Foldable"------ @--- 'reduceWith' 'getSelf'--- @-fold :: (Monoid m, Generator c, Elem c ~ m) => c -> m-fold = reduceWith getSelf-{-# 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, Elem c `Reducer` 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, Elem c `Reducer` m) => (m -> n) -> (Elem c -> Bool) -> c -> n -filterWith f p = f . filter p-{-# INLINE filterWith #-}+-- | A generalization of 'Data.List.cycle' to an arbitrary 'Monoid'. May fail to terminate for some values in some monoids.+cycle :: Monoid m => m -> m+cycle xs = xs' where xs' = xs `mappend` xs' --- | 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 #-}+-- | A generalization of 'Data.List.repeat' to an arbitrary 'Monoid'. May fail to terminate for some values in some monoids.+repeat :: (e `Reducer` m) => e -> m +repeat x = xs where xs = cons x xs -- | A generalization of 'Data.List.replicate' to an arbitrary 'Monoid'. Adapted from -- <http://augustss.blogspot.com/2008/07/lost-and-found-if-i-write-108-in.html>@@ -245,14 +57,6 @@ | y == 1 = x `mappend` z | otherwise = g (x `mappend` x) ((y - 1) `quot` 2) (x `mappend` z) {-# INLINE replicate #-}---- | A generalization of 'Data.List.cycle' to an arbitrary 'Monoid'. May fail to terminate for some values in some monoids.-cycle :: Monoid m => m -> m-cycle xs = xs' where xs' = xs `mappend` xs'---- | A generalization of 'Data.List.repeat' to an arbitrary 'Monoid'. May fail to terminate for some values in some monoids.-repeat :: (e `Reducer` m) => e -> m -repeat x = xs where xs = cons x xs prop_replicate_right_distributive :: (Eq m, Monoid m, Arbitrary m, Integral n) => m -> n -> n -> Bool prop_replicate_right_distributive m x y
Data/Monoid/FromString.hs view
@@ -20,7 +20,7 @@ ) where import Control.Functor.Pointed-import Data.Monoid.Generator+import Data.Generator import Data.Monoid.Reducer import Data.Monoid.Instances () import GHC.Exts
− Data/Monoid/Generator.hs
@@ -1,186 +0,0 @@-{-# LANGUAGE UndecidableInstances, TypeOperators, FlexibleContexts, MultiParamTypeClasses, FlexibleInstances, TypeFamilies #-}---------------------------------------------------------------------------------- |--- Module : Data.Monoid.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.Monoid.Generator- ( module Data.Monoid.Reducer- -- * Generators- , Generator- , Elem- , mapReduce- , mapTo- , mapFrom- -- * Generator Transformers- , Keys(Keys, getKeys)- , Values(Values, getValues)- , Char8(Char8, getChar8)- -- * Combinators- , reduce- , mapReduceWith- , reduceWith- ) where--import Data.Array -import Data.Word (Word8)-import Data.Text (Text)-import Data.Foldable (fold,foldMap)-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 qualified Data.Sequence as Seq-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.Map as Map-import Data.Map (Map)--import Control.Parallel.Strategies-import Data.Monoid.Reducer---- | minimal definition 'mapReduce' or 'mapTo'-class Generator c where- type Elem c :: * - mapReduce :: (e `Reducer` m) => (Elem c -> e) -> c -> m- mapTo :: (e `Reducer` m) => (Elem c -> e) -> m -> c -> m - mapFrom :: (e `Reducer` 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 rwhnf (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 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 (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 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 rwhnf (mapReduce f . Char8) . Lazy8.toChunks . getChar8---- | Apply a 'Reducer' directly to the elements of a 'Generator'-reduce :: (Generator c, Elem c `Reducer` m) => c -> m-reduce = mapReduce id-{-# SPECIALIZE reduce :: (Word8 `Reducer` m) => Strict.ByteString -> m #-}-{-# SPECIALIZE reduce :: (Word8 `Reducer` m) => Lazy.ByteString -> m #-}-{-# SPECIALIZE reduce :: (Char `Reducer` m) => Char8 Strict.ByteString -> m #-}-{-# SPECIALIZE reduce :: (Char `Reducer` m) => Char8 Lazy.ByteString -> m #-}-{-# SPECIALIZE reduce :: (c `Reducer` m) => [c] -> m #-}-{-# SPECIALIZE reduce :: (Generator (FingerTree v e), e `Reducer` m) => FingerTree v e -> m #-}-{-# SPECIALIZE reduce :: (Char `Reducer` m) => Text -> m #-}-{-# SPECIALIZE reduce :: (e `Reducer` m) => Seq e -> m #-}-{-# SPECIALIZE reduce :: (Int `Reducer` m) => IntSet -> m #-}-{-# SPECIALIZE reduce :: (a `Reducer` m) => Set a -> m #-}-{-# SPECIALIZE reduce :: ((Int,v) `Reducer` m) => IntMap v -> m #-}-{-# SPECIALIZE reduce :: ((k,v) `Reducer` m) => Map k v -> m #-}-{-# SPECIALIZE reduce :: (Int `Reducer` m) => Keys (IntMap v) -> m #-}-{-# SPECIALIZE reduce :: (k `Reducer` m) => Keys (Map k v) -> m #-}-{-# SPECIALIZE reduce :: (v `Reducer` m) => Values (IntMap v) -> m #-}-{-# SPECIALIZE reduce :: (v `Reducer` m) => Values (Map k v) -> m #-}--mapReduceWith :: (Generator c, e `Reducer` m) => (m -> n) -> (Elem c -> e) -> c -> n-mapReduceWith f g = f . mapReduce g-{-# INLINE mapReduceWith #-}--reduceWith :: (Generator c, Elem c `Reducer` m) => (m -> n) -> c -> n-reduceWith f = f . reduce-{-# INLINE reduceWith #-}
− Data/Monoid/Generator/Free.hs
@@ -1,114 +0,0 @@-{-# LANGUAGE UndecidableInstances , FlexibleContexts , MultiParamTypeClasses , FlexibleInstances , GeneralizedNewtypeDeriving, ExistentialQuantification, TypeFamilies #-}---------------------------------------------------------------------------------- |--- Module : Data.Monoid.Generator.Free--- Copyright : (c) Edward Kmett 2009--- License : BSD-style--- Maintainer : ekmett@gmail.com--- Stability : experimental--- Portability : non-portable (MPTCs)-----------------------------------------------------------------------------------module Data.Monoid.Generator.Free- ( module Data.Monoid.Generator- , module Data.Monoid.Reducer- , Free (AnyGenerator)- ) where--import Control.Functor.Pointed-import Control.Monad-import Data.Monoid.Generator-import Data.Foldable-import Data.Monoid.Reducer-import Data.Monoid.Additive-import qualified Data.Monoid.Combinators as M-import Data.Monoid.Self--data Free a - = a `Cons` Free a- | Free a `Snoc` a- | Free a `Plus` Free a- | Unit a- | Empty- | forall c. (Generator c, Elem c ~ a) => AnyGenerator c--instance Eq a => Eq (Free a) where- a == b = M.toList a == M.toList b- a /= b = M.toList a == M.toList b--instance Ord a => Ord (Free a) where- a <= b = M.toList a <= M.toList b- a >= b = M.toList a >= M.toList b- a < b = M.toList a < M.toList b- a > b = M.toList a > M.toList b- a `compare` b = M.toList a `compare` M.toList b--instance Monoid (Free a) where- mempty = Empty- mappend = Plus--instance Reducer a (Free a) where- unit = Unit-- snoc Empty a = Unit a- snoc a b = Snoc a b-- cons b Empty = Unit b- cons a b = Cons a b --instance Functor Free where- fmap f (a `Cons` b) = f a `Cons` fmap f b- fmap f (a `Snoc` b) = fmap f a `Snoc` f b- fmap f (a `Plus` b) = fmap f a `Plus` fmap f b- fmap f (Unit a) = Unit (f a)- fmap _ Empty = Empty- fmap f (AnyGenerator c) = mapReduce f c--instance Pointed Free where- point = Unit--instance Monad Free where- return = Unit- a `Cons` b >>= k = k a `Plus` (b >>= k)- a `Snoc` b >>= k = (a >>= k) `Plus` k b- a `Plus` b >>= k = (a >>= k) `Plus` (b >>= k)- Unit a >>= k = k a- Empty >>= _ = Empty- AnyGenerator c >>= k = getSelf (mapReduce k c)--instance MonadPlus Free where- mzero = Empty- mplus = Plus--instance Foldable Free where- foldMap f (a `Cons` b) = f a `mappend` foldMap f b- foldMap f (a `Snoc` b) = foldMap f a `mappend` f b- foldMap f (a `Plus` b) = foldMap f a `mappend` foldMap f b- foldMap f (Unit a) = f a - foldMap _ Empty = mempty- foldMap f (AnyGenerator c) = M.foldMap f c--instance Generator (Free a) where- type Elem (Free a) = a- mapReduce f (a `Cons` b) = f a `cons` mapReduce f b- mapReduce f (a `Snoc` b) = mapReduce f a `snoc` f b- mapReduce f (a `Plus` b) = mapReduce f a `plus` mapReduce f b- mapReduce f (Unit a) = unit (f a)- mapReduce _ Empty = mempty- mapReduce f (AnyGenerator c) = mapReduce f c- - mapTo f m (a `Cons` b) = m `plus` (f a `cons` mapReduce f b)- mapTo f m (a `Snoc` b) = mapTo f m a `snoc` f b- mapTo f m (a `Plus` b) = mapTo f m a `plus` mapReduce f b- mapTo f m (Unit a) = m `snoc` f a- mapTo _ m Empty = m - mapTo f m (AnyGenerator c) = mapTo f m c- - mapFrom f (a `Cons` b) m = f a `cons` mapFrom f b m - mapFrom f (a `Snoc` b) m = mapFrom f a (f b `cons` m)- mapFrom f (a `Plus` b) m = mapReduce f a `plus` mapFrom f b m- mapFrom f (Unit a) m = f a `cons` m- mapFrom _ Empty m = m - mapFrom f (AnyGenerator c) m = mapFrom f c m
− Data/Monoid/Generator/LZ78.hs
@@ -1,114 +0,0 @@-{-# LANGUAGE TypeFamilies, MultiParamTypeClasses #-}---------------------------------------------------------------------------------- |--- Module : Data.Monoid.Generator.LZ78--- Copyright : (c) Edward Kmett 2009--- License : BSD-style--- Maintainer : ekmett@gmail.com--- Stability : experimental--- Portability : portable------ Compression algorithms are all about exploiting redundancy. When applying--- an expensive 'Reducer' to a redundant source, it may be better to --- extract the structural redundancy that is present. 'LZ78' is a compression--- algorithm that does so, without requiring the dictionary to be populated--- with all of the possible values of a data type unlike its later --- refinement LZW, and which has fewer comparison reqirements during encoding--- than its earlier counterpart LZ77. Since we aren't storing these as a --- bitstream the LZSS refinement of only encoding pointers once you cross--- the break-even point is a net loss. ---------------------------------------------------------------------------------module Data.Monoid.Generator.LZ78 - ( module Data.Monoid.Generator- -- * Lempel-Ziv 78 - , LZ78- -- * Decoding- , decode- -- * Encoding- , encode- , encodeEq- -- * QuickCheck Properties- , prop_decode_encode- , prop_decode_encodeEq- ) where--import qualified Data.Sequence as Seq-import Data.Sequence (Seq,(|>))-import qualified Data.Map as Map-import Data.Map (Map)-import qualified Data.List as List-import Data.Monoid.Generator-import Data.Foldable-import Data.Monoid.Self---- | An LZ78 compressing 'Generator', which supports efficient 'mapReduce' operations--data Token a = Token a {-# UNPACK #-} !Int - deriving (Eq,Ord,Show,Read)---- after using the Functor instance the encoding may no longer be minimal-instance Functor Token where- fmap f (Token a n) = Token (f a) n--newtype LZ78 a = LZ78 { getLZ78 :: [Token a] } - deriving (Eq,Ord,Show)--emptyDict :: Monoid m => Seq m-emptyDict = Seq.singleton mempty--instance Generator (LZ78 a) where- type Elem (LZ78 a) = a- mapTo f m (LZ78 xs) = mapTo' f m emptyDict xs--instance Functor LZ78 where- fmap f = LZ78 . fmap (fmap f) . getLZ78--instance Foldable LZ78 where- foldMap f = getSelf . mapReduce f- fold = getSelf . reduce- -mapTo' :: (e `Reducer` m) => (a -> e) -> m -> Seq m -> [Token a] -> m-mapTo' _ m _ [] = m-mapTo' f m s (Token c w:ws) = m `mappend` mapTo' f v (s |> v) ws - where - v = Seq.index s w `mappend` unit (f c)---- | a type-constrained 'reduce' operation- -decode :: LZ78 a -> [a]-decode = reduce---- | contruct an LZ78-compressed 'Generator' using a 'Map' internally, requires an instance of Ord.--encode :: Ord a => [a] -> LZ78 a-encode = LZ78 . encode' Map.empty 1 0--encode' :: Ord a => Map (Token a) Int -> Int -> Int -> [a] -> [Token a]-encode' _ _ p [c] = [Token c p]-encode' d f p (c:cs) = let t = Token c p in case Map.lookup t d of- Just p' -> encode' d f p' cs- Nothing -> t : encode' (Map.insert t f d) (succ f) 0 cs-encode' _ _ _ [] = []---- | contruct an LZ78-compressed 'Generator' using a list internally, requires an instance of Eq.--encodeEq :: Eq a => [a] -> LZ78 a-encodeEq = LZ78 . encodeEq' [] 1 0--encodeEq' :: Eq a => [(Token a,Int)] -> Int -> Int -> [a] -> [Token a]-encodeEq' _ _ p [c] = [Token c p]-encodeEq' d f p (c:cs) = let t = Token c p in case List.lookup t d of- Just p' -> encodeEq' d f p' cs- Nothing -> t : encodeEq' ((t,f):d) (succ f) 0 cs-encodeEq' _ _ _ [] = []---- | QuickCheck property: decode . encode = id-prop_decode_encode :: Ord a => [a] -> Bool-prop_decode_encode xs = decode (encode xs) == xs---- | QuickCheck property: decode . encodeEq = id-prop_decode_encodeEq :: Eq a => [a] -> Bool-prop_decode_encodeEq xs = decode (encodeEq xs) == xs
− Data/Monoid/Generator/RLE.hs
@@ -1,100 +0,0 @@-{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, TypeOperators, FlexibleInstances, FlexibleContexts #-}---------------------------------------------------------------------------------- |--- Module : Data.Monoid.Generator.RLE--- Copyright : (c) Edward Kmett 2009--- License : BSD-style--- Maintainer : ekmett@gmail.com--- Stability : experimental--- Portability : portable------ Compression algorithms are all about exploiting redundancy. When applying--- an expensive 'Reducer' to a redundant source, it may be better to --- extract the structural redundancy that is present. Run length encoding--- can do so for long runs of identical inputs.--------------------------------------------------------------------------------module Data.Monoid.Generator.RLE- ( module Data.Monoid.Generator- , RLE(RLE, getRLE)- , Run(Run)- , decode- , encode- , encodeList- , prop_decode_encode- , prop_decode_encodeList- ) where--import qualified Data.Sequence as Seq-import Data.Sequence (Seq,(|>),(<|),ViewL(..),ViewR(..),(><),viewl,viewr)-import Data.Foldable-import Data.Monoid.Generator-import qualified Data.Monoid.Combinators as Monoid -import Control.Functor.Pointed---- | A single run with a strict length.-data Run a = Run a {-# UNPACK #-} !Int--instance Functor Run where- fmap f (Run a n) = Run (f a) n--instance Pointed Run where- point a = Run a 1---- | A 'Generator' which supports efficient 'mapReduce' operations over run-length encoded data.-newtype RLE f a = RLE { getRLE :: f (Run a) } --instance Functor f => Functor (RLE f) where- fmap f = RLE . fmap (fmap f) . getRLE--instance Foldable f => Generator (RLE f a) where- type Elem (RLE f a) = a- mapReduce f = foldMap run . getRLE where- run (Run a n) = unit (f a) `Monoid.replicate` n--decode :: Foldable f => RLE f a -> [a]-decode = reduce---- | naive left to right encoder--encodeList :: Eq a => [a] -> RLE [] a-encodeList [] = RLE []-encodeList (a:as) = RLE (point a `before` as)--before :: Eq a => Run a -> [a] -> [Run a]-r `before` [] = [r]-r@(Run a n) `before` (b:bs) | a == b = Run a (n+1) `before` bs- | otherwise = r : point b `before` bs---- | QuickCheck property: decode . encode = id-prop_decode_encodeList :: Eq a => [a] -> Bool-prop_decode_encodeList xs = decode (encode xs) == xs---- One nice property that run-length encoding has is that it can be computed monoidally as follows--instance Eq a => Monoid (RLE Seq a) where- mempty = RLE Seq.empty- RLE l `mappend` RLE r = viewr l `merge` viewl r where- (l' :> Run a m) `merge` (Run b n :< r')- | a == b = RLE ((l' |> Run a (m+n)) >< r')- | otherwise = RLE (l >< r)- EmptyR `merge` _ = RLE r- _ `merge` EmptyL = RLE l--instance Eq a => Reducer a (RLE Seq a) where- unit = RLE . Seq.singleton . point- cons a (RLE r) = case viewl r of- Run b n :< r' | a == b -> RLE (Run a (n+1) <| r')- | otherwise -> RLE (Run a 1 <| r )- EmptyL -> RLE (return (point a))- snoc (RLE l) a = case viewr l of- l' :> Run b n | a == b -> RLE (l' |> Run b (n+1))- | otherwise -> RLE (l |> Run a 1 )- EmptyR -> RLE (return (point a))--encode :: (Generator c, Eq (Elem c)) => c -> RLE Seq (Elem c)-encode = reduce--prop_decode_encode :: (Generator c, Eq (Elem c)) => c -> Bool-prop_decode_encode xs = decode (encode xs) == reduce xs
Data/Monoid/Lexical/SourcePosition.hs view
@@ -33,7 +33,7 @@ import Control.Functor.Extras import Control.Functor.Pointed import Data.Monoid.Reducer.Char-import Data.Monoid.Generator+import Data.Generator import Data.String
Data/Monoid/Lexical/Words.hs view
@@ -33,7 +33,7 @@ import Data.Char (isSpace) import Data.Maybe (maybeToList) import Data.Monoid.Reducer.Char-import Data.Monoid.Generator+import Data.Generator import Control.Functor.Pointed -- | A 'CharReducer' transformer that breaks a 'Char' 'Generator' into distinct words, feeding a 'Char' 'Reducer' each line in turn
Data/Monoid/Monad.hs view
@@ -56,7 +56,7 @@ -- | A 'MonadSum' turns any 'MonadPlus' instance into a 'Monoid'. -- It also provides a 'Multiplicative' instance for a 'Monad' wrapped around a 'Monoid'--- and asserts that any 'MonadPlus' applied to a 'Monoid' forms a 'LeftSemiNearRing' +-- and asserts that any 'MonadPlus' applied to a 'Monoid' forms a 'RightSemiNearRing' -- under these operations. newtype MonadSum m a = MonadSum { getMonadSum :: m a } @@ -83,7 +83,7 @@ instance MonadPlus m => Reducer (m a) (MonadSum m a) where unit = MonadSum -instance (MonadPlus m, Monoid a) => LeftSemiNearRing (MonadSum m a)+instance (MonadPlus m, Monoid a) => RightSemiNearRing (MonadSum m a) -- | if @m@ is a 'Module' over @r@ and @f@ is a 'Monad' then @f `Mon` m@ is a 'Module' as well
Data/Monoid/Multiplicative.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-}+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances, TypeOperators #-} ----------------------------------------------------------------------------- -- |@@ -22,11 +22,11 @@ -- Any 'Monoid' can be turned into a 'Multiplicative' using the 'Exp' wrapper. -- -- Instances are supplied for common Monads of Monoids, in a fashion --- which can be extended if the 'Monad' is a 'MonadPlus' to yield a 'LeftSemiNearRing'+-- which can be extended if the 'Monad' is a 'MonadPlus' to yield a 'RightSemiNearRing' -- -- Instances are also supplied for common Applicatives of Monoids, in a -- fashion which can be extended if the 'Applicative' is 'Alternative' to--- yield a 'LeftSemiNearRing'+-- yield a 'RightSemiNearRing' ----------------------------------------------------------------------------- module Data.Monoid.Multiplicative @@ -65,7 +65,7 @@ import Data.Monoid.Additive import Data.Monoid.FromString-import Data.Monoid.Generator+import Data.Generator import Data.Monoid.Instances () import Data.Monoid.Self @@ -80,6 +80,14 @@ one :: m times :: m -> m -> m +instance Multiplicative m => Multiplicative (Dual m) where+ one = Dual one+ Dual x `times` Dual y = Dual (y `times` x)++instance Multiplicative m => Multiplicative (m `ReducedBy` s) where+ one = Reduction one+ Reduction x `times` Reduction y = Reduction (x `times` y)+ -- | Convert a 'Multiplicative' into a 'Monoid'. Mnemonic: @Log a + Log b = Log (a * b)@ data Log m = Log { getLog :: m } @@ -222,13 +230,10 @@ one = pure undefined times = liftA2 undefined - -- Numeric instances- instance Multiplicative Int where one = 1 times = (*)- instance Multiplicative Integer where one = 1
Data/Monoid/Reducer.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE UndecidableInstances , FlexibleContexts , MultiParamTypeClasses , FlexibleInstances , GeneralizedNewtypeDeriving #-}+{-# LANGUAGE UndecidableInstances , FlexibleContexts , MultiParamTypeClasses , FlexibleInstances , GeneralizedNewtypeDeriving, TypeOperators, ScopedTypeVariables #-} ----------------------------------------------------------------------------- -- |@@ -23,6 +23,7 @@ , foldReduce , pureUnit , returnUnit+ , ReducedBy(Reduction,getReduction) ) where import Control.Applicative@@ -46,6 +47,8 @@ import qualified Data.IntMap as IntMap import Data.IntMap (IntMap) +import Data.Reflection+ import qualified Data.Map as Map import Data.Map (Map)@@ -191,3 +194,12 @@ instance Enum a => Reducer a (BitSet a) where unit m = BitSet.insert m BitSet.empty -}++data (m `ReducedBy` s) = Reduction { getReduction :: m } ++instance Monoid m => Monoid (m `ReducedBy` s) where+ mempty = Reduction mempty+ Reduction a `mappend` Reduction b = Reduction (a `mappend` b)++instance (s `Reflects` (a -> m), Monoid m) => Reducer a (m `ReducedBy` s) where+ unit = Reduction . reflect (undefined :: s)
Data/Monoid/Self.hs view
@@ -25,7 +25,7 @@ import Control.Functor.Pointed import Data.Monoid.Reducer-import Data.Monoid.Generator+import Data.Generator newtype Self m = Self { getSelf :: m } deriving (Monoid)
Data/Ring.hs view
@@ -1,6 +1,3 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-}- ----------------------------------------------------------------------------- -- | -- Module : Data.Ring@@ -20,5 +17,12 @@ import Data.Group import Data.Ring.Semi+import Data.Monoid.Self+import Data.Monoid.FromString class (Group a, SemiRing a) => Ring a++instance Ring r => Ring (Self r)+instance Ring r => Ring (FromString r)+instance Ring r => Ring (ReducedBy r s)+instance Ring r => Ring (Dual r)
+ Data/Ring/Algebra.hs view
@@ -0,0 +1,13 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}+module Data.Ring.Algebra+ ( module Data.Ring.Module+ , Algebra+ ) where++import Data.Ring.Module++-- | +-- @r *. (x * y) = (r *. x) * y = x * (r *. y)@+--+-- @(x * y) .* r = y * (x .* r) = (y .* r) * x@+class (r `Module` m, Multiplicative m) => Algebra r m
Data/Ring/Module/AutomaticDifferentiation.hs view
@@ -1,60 +1,86 @@-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, RankNTypes, FunctionalDependencies, UndecidableInstances, FlexibleContexts #-}++-----------------------------------------------------------------------------+-- |+-- Module : Data.Ring.Module.AutomaticDifferentiation+-- Copyright : (c) Edward Kmett 2009+-- License : BSD-style+-- Maintainer : ekmett@gmail.com+-- Stability : experimental+-- Portability : portable (instances use MPTCs)+--+-----------------------------------------------------------------------------+ module Data.Ring.Module.AutomaticDifferentiation ( module Data.Ring.Module , D+ , d+ , lift ) where -import Prelude hiding ((*),(+),(-),subtract,negate)-import Data.Ring.Sugar+import Prelude import Data.Ring.Module import Data.Monoid.Reducer import Test.QuickCheck import Control.Monad -data D r m = D r m+data D s r m = D r m deriving (Show,Read) -instance (Monoid r, Monoid m) => Monoid (D r m) where+lift :: Monoid m => r -> D s r m+lift x = D x zero++infinitesimal :: (Monoid r, Multiplicative m) => D s r m+infinitesimal = D zero one++instance Eq r => Eq (D s r m) where+ D x _ == D y _ = x == y++instance Ord r => Ord (D s r m) where+ D x _ `compare` D y _ = compare x y++instance (Monoid r, Monoid m) => Monoid (D s r m) where mempty = D mempty mempty- D x m `mappend` D y n = D (x + y) (m + n)+ D x m `mappend` D y n = D (x `mappend` y) (m `mappend` n) -instance (Module r m) => Multiplicative (D r m) where+instance (r `Module` m) => Multiplicative (D s r m) where one = D one zero- D x m `times` D y n = D (x * y) (x *. n + m .* y)+ D x m `times` D y n = D (x `times` y) (x *. n `plus` m .* y) -instance (Group r, Module r m, Group m) => Group (D r m) where+instance (Group r, r `Module` m, Group m) => Group (D s r m) where gnegate (D x m) = D (gnegate x) (gnegate m) D x m `minus` D y n = D (x `minus` y) (m `minus` n) D x m `gsubtract` D y n = D (x `gsubtract` y) (m `gsubtract` n) -instance (LeftSemiNearRing r, Module r m) => LeftSemiNearRing (D r m)-instance (RightSemiNearRing r, Module r m) => RightSemiNearRing (D r m)-instance (SemiRing r, Module r m) => SemiRing (D r m)-instance (Ring r, Module r m, Group m) => Ring (D r m)+instance Num a => Num (D s a a) where+ D x x' + D y y' = D (x + y) (x' + y')+ D x x' * D y y' = D (x * y) (x * y' + x' * y)+ D x x' - D y y' = D (x - y) (x' - y')+ negate (D x x') = D (negate x) (negate x')+ abs (D x x') = D (abs x) (signum x * x')+ signum (D x _) = D (signum x) 0+ fromInteger x = D (fromInteger x) 0 -instance (c `Reducer` r, c `Reducer` m) => Reducer c (D r m) where+instance Fractional a => Fractional (D s a a) where+ recip (D x x') = D (recip x) (-x'/x/x)+ fromRational x = D (fromRational x) 0++instance (LeftSemiNearRing r, Module r m) => LeftSemiNearRing (D s r m)+instance (RightSemiNearRing r, Module r m) => RightSemiNearRing (D s r m)+instance (SemiRing r, Module r m) => SemiRing (D s r m)+instance (Ring r, Module r m, Group m) => Ring (D s r m)++instance (c `Reducer` r, c `Reducer` m) => Reducer c (D s r m) where unit c = D (unit c) (unit c) c `cons` D x m = D (c `cons` x) (c `cons` m) D x m `snoc` c = D (x `snoc` c) (m `snoc` c) -instance (Arbitrary r, Arbitrary m) => Arbitrary (D r m) where+instance (Arbitrary r, Arbitrary m) => Arbitrary (D s r m) where arbitrary = liftM2 D arbitrary arbitrary shrink (D r m) = liftM2 D (shrink r) (shrink m) -instance (CoArbitrary r, CoArbitrary m) => CoArbitrary (D r m) where+instance (CoArbitrary r, CoArbitrary m) => CoArbitrary (D s r m) where coarbitrary (D r m) = coarbitrary r >< coarbitrary m -{---infix 0 ><--(><) :: Multiplicatve a => (a -> a) -> (AD a -> AD a) -> AD a -> AD a-(f >< f') a@(AD a0 a') = D (f a0) (a' * f' a)--data AD r = AD r (Maybe (AD r))--instance (Monoid r) => Monoid (AD r) where- mempty = K mempty- AD x m + AD y n = D (x + y) (m + n)+d :: (Monoid r, Multiplicative m) => (forall s. D s r m -> D s r m) -> (r,m)+d f = (y,y') where D y y' = f infinitesimal -instance (c `Reducer` r) => Reducer c (AD r) where- unit c = c' where c' = AD (unit c) c'---}
Data/Ring/Semi.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE MultiParamTypeClasses #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Ring.Semi@@ -16,7 +17,14 @@ ) where import Data.Ring.Semi.Near+import Data.Monoid.Self+import Data.Monoid.FromString -- | A 'SemiRing' is an instance of both 'Multiplicative' and 'Monoid' where -- 'times' distributes over 'plus'. class (RightSemiNearRing a, LeftSemiNearRing a) => SemiRing a++instance SemiRing r => SemiRing (Self r)+instance SemiRing r => SemiRing (FromString r)+instance SemiRing r => SemiRing (ReducedBy r s)+instance SemiRing r => SemiRing (Dual r)
Data/Ring/Semi/Natural.hs view
@@ -35,8 +35,8 @@ import Data.Monoid.FromString import Data.Monoid.Lexical.SourcePosition import Data.Monoid.Lexical.UTF8.Decoder-import Data.Monoid.Generator.Free-import Data.Monoid.Generator.RLE+import Data.Generator.Free+import Data.Generator.Compressive.RLE import Data.Sequence (Seq) natural :: Integer -> Natural
Data/Ring/Semi/Near.hs view
@@ -38,53 +38,57 @@ import Data.FingerTree import Data.Monoid.FromString import Data.Monoid.Self-import Data.Monoid.Generator+import Data.Generator import qualified Data.Sequence as Seq import Data.Sequence (Seq) import Text.Parsec.Prim --- | @(a + b) * c = (a * c) + (b * c)@-class (Multiplicative m, Monoid m) => RightSemiNearRing m ---- 'Monoid' transformers-instance RightSemiNearRing m => RightSemiNearRing (Self m)-instance RightSemiNearRing m => RightSemiNearRing (FromString m)- -- | @a * (b + c) = (a * b) + (a * c)@ class (Multiplicative m, Monoid m) => LeftSemiNearRing m -- 'Monoid' transformers instance LeftSemiNearRing m => LeftSemiNearRing (Self m) instance LeftSemiNearRing m => LeftSemiNearRing (FromString m)+instance LeftSemiNearRing m => LeftSemiNearRing (ReducedBy m s)+instance RightSemiNearRing m => LeftSemiNearRing (Dual m) +-- | @(a + b) * c = (a * c) + (b * c)@+class (Multiplicative m, Monoid m) => RightSemiNearRing m ++-- 'Monoid' transformers+instance RightSemiNearRing m => RightSemiNearRing (Self m)+instance RightSemiNearRing m => RightSemiNearRing (FromString m)+instance RightSemiNearRing m => RightSemiNearRing (ReducedBy m s)+instance LeftSemiNearRing m => RightSemiNearRing (Dual m)+ -- non-'Monad' instances-instance (Measured v m, Monoid m) => LeftSemiNearRing (FingerTree v m)+instance (Measured v m, Monoid m) => RightSemiNearRing (FingerTree v m) -- 'Monad' instances -- Every 'MonadPlus' over a 'Monoid' with an appropriate 'Multiplicative' instance--- for 'liftM2 mappend' is a 'LeftSemiNearRing' by 'MonadPlus' left-distributivity+-- for 'liftM2 mappend' is a 'RightSemiNearRing' by 'MonadPlus' left-distributivity -instance Monoid m => LeftSemiNearRing [m]+instance Monoid m => RightSemiNearRing [m] -instance Monoid m => LeftSemiNearRing (Maybe m)+instance Monoid m => RightSemiNearRing (Maybe m) -instance Monoid m => LeftSemiNearRing (Seq m)+instance Monoid m => RightSemiNearRing (Seq m) -instance (Stream s m t, Monoid a) => LeftSemiNearRing (ParsecT s u m a)+instance (Stream s m t, Monoid a) => RightSemiNearRing (ParsecT s u m a) -instance (MonadPlus m, Monoid n) => LeftSemiNearRing (SState.StateT s m n)+instance (MonadPlus m, Monoid n) => RightSemiNearRing (SState.StateT s m n) -instance (MonadPlus m, Monoid n) => LeftSemiNearRing (LState.StateT s m n)+instance (MonadPlus m, Monoid n) => RightSemiNearRing (LState.StateT s m n) -instance (MonadPlus m, Monoid n) => LeftSemiNearRing (ReaderT e m n)+instance (MonadPlus m, Monoid n) => RightSemiNearRing (ReaderT e m n) -instance (MonadPlus m, Monoid w, Monoid n) => LeftSemiNearRing (SRWS.RWST r w s m n)+instance (MonadPlus m, Monoid w, Monoid n) => RightSemiNearRing (SRWS.RWST r w s m n) -instance (MonadPlus m, Monoid w, Monoid n) => LeftSemiNearRing (LRWS.RWST r w s m n)+instance (MonadPlus m, Monoid w, Monoid n) => RightSemiNearRing (LRWS.RWST r w s m n) -instance (MonadPlus m, Monoid w, Monoid n) => LeftSemiNearRing (SWriter.WriterT w m n)+instance (MonadPlus m, Monoid w, Monoid n) => RightSemiNearRing (SWriter.WriterT w m n) -instance (MonadPlus m, Monoid w, Monoid n) => LeftSemiNearRing (LWriter.WriterT w m n)+instance (MonadPlus m, Monoid w, Monoid n) => RightSemiNearRing (LWriter.WriterT w m n)
monoids.cabal view
@@ -1,5 +1,5 @@ name: monoids-version: 0.1.21+version: 0.1.25 license: BSD3 license-file: LICENSE author: Edward A. Kmett@@ -30,8 +30,12 @@ array >= 0.2 && < 0.3, reflection >= 0.1 && < 0.2 exposed-modules:+ Data.Field+ Data.Field.VectorSpace Data.Group Data.Group.Combinators+ Data.Group.Multiplicative+ Data.Group.Multiplicative.Sugar Data.Group.Sugar Data.Monoid.Additive Data.Monoid.Additive.Sugar@@ -39,10 +43,11 @@ Data.Monoid.Categorical Data.Monoid.Combinators Data.Monoid.FromString- Data.Monoid.Generator- Data.Monoid.Generator.Free- Data.Monoid.Generator.LZ78- Data.Monoid.Generator.RLE+ Data.Generator+ Data.Generator.Combinators+ Data.Generator.Compressive.LZ78+ Data.Generator.Compressive.RLE+ Data.Generator.Free Data.Monoid.Instances Data.Monoid.Lexical.SourcePosition Data.Monoid.Lexical.UTF8.Decoder@@ -57,6 +62,7 @@ Data.Monoid.Self Data.Monoid.Union Data.Ring+ Data.Ring.Algebra Data.Ring.Boolean Data.Ring.FromNum Data.Ring.ModularArithmetic@@ -68,5 +74,5 @@ Data.Ring.Semi.Ord Data.Ring.Semi.Tropical Data.Ring.Sugar- + ghc-options: -Wall -fno-warn-duplicate-exports