packages feed

monoids 0.1.25 → 0.1.28

raw patch · 6 files changed

+352/−6 lines, 6 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Data.Ring.Module: instance (HasUnionWith f, Ord r, Eq r, RightSemiNearRing r) => LeftModule r (UnionWith f r)
+ Data.Ring.Module: instance (HasUnionWith f, Ord r, Eq r, RightSemiNearRing r) => Module r (UnionWith f r)
+ Data.Ring.Module: instance (HasUnionWith f, Ord r, Eq r, RightSemiNearRing r) => RightModule r (UnionWith f r)
+ Data.Ring.Semi.BitSet: (\\) :: (Enum a, Bounded a) => BitSet a -> BitSet a -> BitSet a
+ Data.Ring.Semi.BitSet: complement :: (Enum a, Bounded a) => BitSet a -> BitSet a
+ Data.Ring.Semi.BitSet: data BitSet a
+ Data.Ring.Semi.BitSet: delete :: (Enum a) => a -> BitSet a -> BitSet a
+ Data.Ring.Semi.BitSet: empty :: BitSet a
+ Data.Ring.Semi.BitSet: fromDistinctAscList :: (Enum a) => [a] -> BitSet a
+ Data.Ring.Semi.BitSet: fromList :: (Enum a) => [a] -> BitSet a
+ Data.Ring.Semi.BitSet: full :: (Enum a, Bounded a) => BitSet a
+ Data.Ring.Semi.BitSet: insert :: (Enum a) => a -> BitSet a -> BitSet a
+ Data.Ring.Semi.BitSet: instance (Bounded a, Enum a) => Algebra Natural (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Bounded a, Enum a) => LeftModule (BitSet a) (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Bounded a, Enum a) => LeftSemiNearRing (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Bounded a, Enum a) => Module (BitSet a) (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Bounded a, Enum a) => Multiplicative (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Bounded a, Enum a) => RightModule (BitSet a) (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Bounded a, Enum a) => RightSemiNearRing (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Bounded a, Enum a) => SemiRing (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Enum a) => Generator (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Enum a) => LeftModule Natural (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Enum a) => Module Natural (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Enum a) => Monoid (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Enum a) => Reducer a (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Enum a) => RightModule Natural (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Enum a, Bounded a) => Bounded (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Enum a, Bounded a) => Enum (BitSet a)
+ Data.Ring.Semi.BitSet: instance (Typeable a) => Data (BitSet a)
+ Data.Ring.Semi.BitSet: instance Eq (BitSet a)
+ Data.Ring.Semi.BitSet: instance Ord (BitSet a)
+ Data.Ring.Semi.BitSet: instance Show (BitSet a)
+ Data.Ring.Semi.BitSet: instance Typeable1 BitSet
+ Data.Ring.Semi.BitSet: member :: (Enum a) => a -> BitSet a -> Bool
+ Data.Ring.Semi.BitSet: null :: BitSet a -> Bool
+ Data.Ring.Semi.BitSet: singleton :: (Enum a) => a -> BitSet a
+ Data.Ring.Semi.BitSet: size :: BitSet a -> Int
+ Data.Ring.Semi.BitSet: toInteger :: BitSet a -> Integer
+ Data.Ring.Semi.Near.Trie: Trie :: m -> m -> UnionWith (Map c) (Trie c m) -> Trie c m
+ Data.Ring.Semi.Near.Trie: children :: Trie c m -> UnionWith (Map c) (Trie c m)
+ Data.Ring.Semi.Near.Trie: data Trie c m
+ Data.Ring.Semi.Near.Trie: empty :: (Ord c, Monoid m) => Trie c m
+ Data.Ring.Semi.Near.Trie: instance (Eq c, Eq m) => Eq (Trie c m)
+ Data.Ring.Semi.Near.Trie: instance (Ord c, Monoid m) => Monoid (Trie c m)
+ Data.Ring.Semi.Near.Trie: instance (Ord c, Reducer c m) => Reducer c (Trie c m)
+ Data.Ring.Semi.Near.Trie: instance (Show c, Show m) => Show (Trie c m)
+ Data.Ring.Semi.Near.Trie: instance Functor (Trie c)
+ Data.Ring.Semi.Near.Trie: label :: Trie c m -> m
+ Data.Ring.Semi.Near.Trie: null :: (Ord c) => Trie c m -> Bool
+ Data.Ring.Semi.Near.Trie: singleton :: (Ord c, Reducer c m) => c -> Trie c m
+ Data.Ring.Semi.Near.Trie: total :: Trie c m -> m
- Data.Monoid.Union: class HasUnionWith f
+ Data.Monoid.Union: class (Functor f) => HasUnionWith f

Files

Data/Monoid/Combinators.hs view
@@ -27,7 +27,6 @@     ) where  import Prelude hiding (replicate, cycle, repeat)-import Control.Monad (MonadPlus) import Data.Monoid.Reducer import Test.QuickCheck 
Data/Monoid/Union.hs view
@@ -29,7 +29,7 @@  import Control.Functor.Pointed -import Data.Monoid.Reducer (Reducer, unit, cons, snoc, Monoid, mappend, mempty)+import Data.Monoid.Reducer  -- | A Container suitable for the 'Union' 'Monoid' class HasUnion f where@@ -82,7 +82,7 @@     extract = getUnion  -- | Polymorphic containers that we can supply an operation to handle unions with-class HasUnionWith f where+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 #-}     unionWith :: (a -> a -> a) -> f a -> f a -> f a@@ -96,7 +96,6 @@     emptyWith = Map.empty     unionWith = Map.unionWith - -- | The 'Monoid' @('unionWith mappend','empty')@ for containers full of monoids. newtype UnionWith f m = UnionWith { getUnionWith :: f m }      deriving (Eq,Ord,Show,Read,Functor,Pointed,Monad)@@ -108,3 +107,4 @@ instance (HasUnionWith f, Monoid m) => Reducer (f m) (UnionWith f m) where     unit = UnionWith +-- we want an absorbing 0, for that we need a seminearring and a notion of equality
Data/Ring/Module.hs view
@@ -24,6 +24,8 @@     ) where  import Data.Ring+import Data.Monoid.Union+ -- import qualified Data.Monoid.Combinators as Monoid  -- | @ (x * y) *. m = x * (y *. m) @@@ -59,3 +61,13 @@ instance (Module r m, Module r n, Module r o) => Module r (m,n,o) instance (Module r m, Module r n, Module r o, Module r p) => Module r (m,n,o,p) instance (Module r m, Module r n, Module r o, Module r p, Module r q) => Module r (m,n,o,p,q)+++-- we want an absorbing 0, for that we need a seminearring and a notion of equality+instance (HasUnionWith f, Ord r, Eq r, RightSemiNearRing r) => LeftModule r (UnionWith f r) where+    r *. m | r == zero = zero+           | otherwise = fmap (r `times`) m+instance (HasUnionWith f, Ord r, Eq r, RightSemiNearRing r) => RightModule r (UnionWith f r) where+    m .* r | r == zero = zero+           | otherwise = fmap (`times` r) m+instance (HasUnionWith f, Ord r, Eq r, RightSemiNearRing r) => Module r (UnionWith f r) where
+ Data/Ring/Semi/BitSet.hs view
@@ -0,0 +1,279 @@+{-# LANGUAGE FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, DeriveDataTypeable, BangPatterns, PatternGuards, TypeFamilies #-}+module Data.Ring.Semi.BitSet+    ( module Data.Monoid.Reducer+    , BitSet+    , empty+    , singleton+    , null+    , full+    , complement+    , insert+    , delete+    , fromList+    , fromDistinctAscList+    , toInteger+    , (\\)+    , member+    , size+    ) where++import Prelude hiding ( null, exponent, toInteger )+import Data.Bits hiding ( complement )+import qualified Data.Bits as Bits+import Data.Data+import Data.Ring.Semi.Natural+import Data.Monoid.Reducer+import Data.Generator+import Data.Ring.Algebra++data BitSet a = BS +        { _countAtLeast  :: {-# UNPACK #-} !Int       -- ^ a conservative upper bound on the element count+        , _countAtMost   :: {-# UNPACK #-} !Int       -- ^ a conservative lower bound on the element count+        , _count         :: Int                       -- ^ the actual element count (lazy) used when the above two disagree+        , exponent       :: {-# UNPACK #-} !Int       -- ^ low water mark+        , _hwm           :: {-# UNPACK #-} !Int       -- ^ high water mark+        , mantissa       :: {-# UNPACK #-} !Integer   -- ^ the set of bits. TODO: negative mantissa = complement+        , _universe      :: (Int,Int)                 -- ^ invariant: mantissa < 0 => universe = (fromEnum minBound,fromEnum maxBound)+        } deriving (Data, Typeable,Show)++debug :: BitSet a -> (Int,Int,Int,Int,Int,Integer)+debug (BS a b c d e f _) = (a,b,c,d,e,f)++-- | internal smart constructor: makes sure the count is forced when known+bs :: Int -> Int -> Int -> Int -> Int -> Integer -> (Int,Int) -> BitSet a+bs !a !b c !l !h !m u | a == b = BS a a a l h m u+                      | otherwise = BS a b c l h m u+{-# INLINE bs #-}++-- instance (Enum a, Show a) => Show (BitSet a) where+--    show s = "fromDistinctAscList " ++ show (toList s) ++ ++-- | /O(d)/ where /d/ is absolute deviation in fromEnum from the least element in the set.+toList :: Enum a => BitSet a -> [a]+toList (BS _ _ _ l h m u) +    | m < 0 = map toEnum [ul..max (pred l) ul] ++ toList' l (map toEnum [min (succ h) uh..uh])+    | otherwise = toList' 0 []+    where+        ~(ul,uh) = u+        toList' :: Enum a => Int -> [a] -> [a]+        toList' !n t | n > h = t+                     | testBit m (n - l) = toEnum n : toList' (n+1) t+                     | otherwise         = toList' (n+1) t+{-# INLINE toList #-}++-- | The empty bit set.+empty :: BitSet a+empty = BS 0 0 0 0 0 0 undefined+{-# INLINE empty #-}++singleton :: Enum a => a -> BitSet a +singleton x = BS 1 1 1 e e 1 undefined where e = fromEnum x+{-# INLINE singleton #-}++-- | Is the bit set empty? Asymptotically faster than checking if size == 0 in some cases.+null :: BitSet a -> Bool+null (BS a b c _ _ _ _) +    | a > 0     = False+    | b == 0    = True+    | otherwise = c == 0 +{-# INLINE null #-}++full :: (Enum a, Bounded a) => BitSet a+full = complement empty ++universeOf :: (Bounded a, Enum a) => BitSet a -> (Int,Int)+universeOf x = (fromEnum (minBound `asArgTypeOf` x), fromEnum (maxBound `asArgTypeOf` x))++-- ensures valid universe, may result in negative bitset, note recalculation of universe+complement :: (Enum a, Bounded a) => BitSet a -> BitSet a +complement r@(BS a b c l h m _) = BS (Bits.complement b) (Bits.complement a) (Bits.complement c) l h (Bits.complement m) (universeOf r)++-- proof obligation: either the value is already complemented or it is a complement-complement, note retention of u+recomplement :: BitSet a -> BitSet a +recomplement (BS a b c l h m u) = BS (Bits.complement b) (Bits.complement a) (Bits.complement c) l h (Bits.complement m) u++-- | /O(d * n)/ Make a @BitSet@ from a list of items.+fromList :: Enum a => [a] -> BitSet a+fromList = foldr insert empty +{-# INLINE fromList #-}++fromDistinctAscList :: Enum a => [a] -> BitSet a +fromDistinctAscList [] = empty+fromDistinctAscList (c:cs) = fromDistinctAscList' cs 1 0 1 +    where+        l = fromEnum c+        fromDistinctAscList' :: Enum a => [a] -> Int -> Int -> Integer -> BitSet a+        fromDistinctAscList' [] !n !h !m  = BS n n n l h m undefined+        fromDistinctAscList' (c':cs') !n _ !m = fromDistinctAscList' cs' (n+1) h' (setBit m (h' - l))+            where+                h' = fromEnum c'+{-# INLINE fromDistinctAscList #-}++-- | /O(d)/ Insert an item into the bit set.+insert :: Enum a => a -> BitSet a -> BitSet a+insert x r@(BS a b c l h m u) +    | m < 0, e < l = r +    | m < 0, e > h = r+    | e < l = bs (a+1) (b+1) (c+1) e (h - e) (shiftL m (l - e) .|. 1) u+    | e > h = bs (a+1) (b+1) (c+1) l p (setBit m p) u+    | testBit m (e - l) = r +    | otherwise = bs (a+1) (b+1) (c+1) l h (setBit m p) u+    where +        e = fromEnum x+        p = e - l +{-# INLINE insert #-}++-- | /O(d)/ Delete an item from the bit set.+delete :: Enum a => a -> BitSet a -> BitSet a+delete x r@(BS a b c l h m u) +    | m < 0, e < l = bs (a+1) (b+1) (c+1) e (h - e) (shiftL m (l - e) .&. Bits.complement 1) u+    | m < 0, e > h = bs (a+1) (b+1) (c+1) l p (clearBit m p) u+    | e < l       = r+    | e > h       = r+    | testBit m p = bs (a-1) (b-1) (c-1) l h (clearBit m p) u+    | otherwise   = r+    where +        e = fromEnum x+        p = e - l+{-# INLINE delete #-}++-- | /O(testBit on Integer)/ Ask whether the item is in the bit set.+member :: Enum a => a -> BitSet a -> Bool+member x (BS _ _ _ l h m _) +    | e < l     = m < 0 +    | e > h     = m > 0+    | otherwise = testBit m (e - l)+    where +        e = fromEnum x+{-# INLINE member #-}++-- | /O(1)/ or /O(d)/ The number of elements in the bit set.+size :: BitSet a -> Int+size (BS a b c _ _ m (ul,uh)) +    | a == b, m >= 0 = a+    | a == b         = uh - ul - a +    | m >= 0         = c+    | otherwise      = uh - ul - c ++-- | /O(d)/ convert to an Integer representation. Discards negative elements+toInteger :: BitSet a -> Integer+toInteger x = mantissa x `shift` exponent x++union :: BitSet a -> BitSet a -> BitSet a +union x@(BS a b c l h m u) y@(BS a' b' c' l' h' m' u')+    | l' < l    = union y x                                                         -- ensure left side has lower exponent+    | b == 0    = y                                                                 -- fast empty union+    | b' == 0   = x                                                                 -- fast empty union+    | a == -1   = BS (-1) (-1) (-1) 0 0 (-1) u                                      -- fast full union, recomplement obligation met by negative size+    | a' == -1  = BS (-1) (-1) (-1) 0 0 (-1) u'                                     -- fast full union, recomplement obligation met by negative size+    | m < 0, m' < 0 = recomplement (intersection (recomplement x) (recomplement y)) -- appeal to intersection, recomplement obligation met by 2s complement+    | m' < 0    = recomplement (pseudoDiff (recomplement y) x u')                      -- union with complement, recomplement obligation met by 2s complement -- THESE ARE WRONG FIX!+    | m < 0     = recomplement (pseudoDiff (recomplement x) y u)                      -- union with complement, recomplement obligation met by 2s complement -- THESE ARE WRONG FIX!+    | h < l'    = bs (a + a') (b + b') (c + c') l h' m'' u                          -- disjoint positive ranges+    | otherwise = bs (a `max` a') (b + b') (recount m'') l (h `max` h') m'' u       -- overlapped positives+    where +        m'' = m .|. shiftL m' (l' - l)++intersection :: BitSet a -> BitSet a -> BitSet a +intersection x@(BS a b _ l h m u) y@(BS a' b' _ l' h' m' u')+    | l' < l = intersection y x                                 +    | b == 0 = empty+    | b' == 0 = empty+    | a == -1 = y+    | a' == -1 = x+    | m < 0, m' < 0 = recomplement (union (recomplement x) (recomplement y))+    | m' < 0 = pseudoDiff x (recomplement y) u'+    | m < 0 = pseudoDiff y (recomplement x) u+    | h < l' = empty +    | otherwise = bs 0 (b `min` b') (recount m'') l'' (h `min` h') m'' u+    where+        l'' = max l l'+        m'' = shift m (l'' - l) .&. shift m' (l'' - l')++-- we know m >= 0, m' >= 0, a /= -1, a' /= -1, b /= 0, b' /= 0, u' is the universe of discourse+pseudoDiff :: BitSet a -> BitSet a -> (Int,Int) -> BitSet a +pseudoDiff x@(BS a _ _ l h m _) (BS _ b' _ l' h' m' _) u''+    | h < l' = x+    | h' < l = x+    | otherwise = bs (max (a - b') 0) a (recount m'') l h m'' u''+    where m'' = m .&. shift (Bits.complement m') (l' - l)++(\\) :: (Enum a, Bounded a) => BitSet a -> BitSet a -> BitSet a +x \\ y = x `intersection` complement y++-- TODO: fix this so that it handles complements correctly+instance Eq (BitSet a) where+    BS _ _ _ l _ m _ == BS _ _ _ l' _ m' _ = shift m (l'' - l) == shift m' (l'' - l) where l'' = min l l'+    BS _ _ _ l _ m _ /= BS _ _ _ l' _ m' _ = shift m (l'' - l) /= shift m' (l'' - l) where l'' = min l l'++instance Ord (BitSet a) where+    BS _ _ _ l _ m _ `compare` BS _ _ _ l' _ m' _ = shift m (l'' - l) `compare` shift m' (l'' - l) where l'' = min l l'++instance (Enum a, Bounded a) => Bounded (BitSet a) where+    minBound = empty+    maxBound = result where+        result = BS n n n l h m (l,h)+        n = h - l + 1+        l = fromEnum (minBound `asArgTypeOf` result)+        h = fromEnum (maxBound `asArgTypeOf` result)+        m = setBit 0 n - 1++asArgTypeOf :: a -> f a -> a+asArgTypeOf = const+{-# INLINE asArgTypeOf #-}++recount :: Integer -> Int+recount = recount' 0 where+    recount' :: Int -> Integer -> Int+    recount' !n 0 = n+    recount' !n !m = recount' (if testBit m 0 then n+1 else n) (shiftR m 1)++-- note that operations on values generated by toEnum are pretty slow because the bounds are suboptimal+instance (Enum a, Bounded a) => Enum (BitSet a) where+    fromEnum b@(BS _ _ _ l _ m _) = fromInteger (shiftL m (l - l'))+        where +            l' = fromEnum (minBound `asArgTypeOf` b)+    toEnum i = result +        where+            result = BS a i (recount m) l h m undefined -- n <= 2^n, so i serves as a valid upper bound+            l = fromEnum (minBound `asArgTypeOf` result)+            h = fromEnum (maxBound `asArgTypeOf` result)+            m = fromIntegral i+            a | m /= 0 = 1 -- allow a fast null check, but not much else+              | otherwise = 0+        +instance Enum a => Monoid (BitSet a) where+    mempty = empty+    mappend = union++instance Enum a => Reducer a (BitSet a) where+    unit = singleton+    snoc = flip insert+    cons = insert++instance (Bounded a, Enum a) => Multiplicative (BitSet a) where+    one = full+    times = intersection++instance (Bounded a, Enum a) => LeftSemiNearRing (BitSet a)+instance (Bounded a, Enum a) => RightSemiNearRing (BitSet a)+instance (Bounded a, Enum a) => SemiRing (BitSet a)++-- idempotent monoid+instance Enum a => LeftModule Natural (BitSet a) where+    0 *. _ = empty+    _ *. m = m+instance Enum a => RightModule Natural (BitSet a) where+    _ .* 0 = empty+    m .* _ = m+instance Enum a => Module Natural (BitSet a)++instance (Bounded a, Enum a) => LeftModule (BitSet a) (BitSet a) where (*.) = times+instance (Bounded a, Enum a) => RightModule (BitSet a) (BitSet a) where (.*) = times+instance (Bounded a, Enum a) => Module (BitSet a) (BitSet a)++instance (Bounded a, Enum a) => Algebra Natural (BitSet a)+    +instance Enum a => Generator (BitSet a) where+    type Elem (BitSet a) = a+    mapReduce f = mapReduce f . toList
+ Data/Ring/Semi/Near/Trie.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FlexibleContexts #-}+module Data.Ring.Semi.Near.Trie +    ( module Data.Ring.Semi.Near+    , Trie(Trie, total, label, children)+    , singleton+    , empty+    , null+    ) where+    ++import Data.Map (Map)+import qualified Data.Map as Map+--import Data.Monoid.Multiplicative+--import Data.Monoid.Reducer+import Data.Monoid.Union hiding (empty)+--import Data.Ring.Module+import Data.Ring.Semi.Near+import Prelude hiding (null)++singleton :: (Ord c, c `Reducer` m) => c -> Trie c m +singleton = unit++empty :: (Ord c, Monoid m) => Trie c m+empty = zero++null :: Ord c => Trie c m -> Bool+null = Map.null . getUnionWith . children++data Trie c m = Trie { total :: m, label :: m, children :: UnionWith (Map c) (Trie c m) }+    deriving (Eq,Show)++instance Functor (Trie c) where+    fmap f (Trie t e r) = Trie (f t) (f e) (fmap (fmap f) r)++instance (Ord c, Monoid m) => Monoid (Trie c m) where+    mempty = Trie mempty mempty mempty+    Trie x y z `mappend` Trie x' y' z' = Trie (x `mappend` x') (y `mappend` y') (z `mappend` z')++instance (Ord c, c `Reducer` m) => Reducer c (Trie c m) where+    unit c = Trie r zero . UnionWith $ flip Map.singleton (Trie r r zero) c where r = unit c++{-+instance (Ord c, Eq r, RightSemiNearRing r) => Multiplicative (Trie c r) where+    one = Trie one one zero+    Trie t e r `times` rhs@(Trie t' e' r') = +        Trie (t `times` t') (e `times` e') (r .* rhs `plus` lhs *. r') where+            lhs = Trie e e zero `asTypeOf` rhs++instance (Ord c, Eq r, RightSemiNearRing r) => RightSemiNearRing (Trie c r)++toList :: (Ord c, c `Reducer` [c]) => Trie c m -> [[c]]+toList = fmap merge . Map.assocs . getUnionWith . children where+    merge (k,t) = k `times` toList t+-}
monoids.cabal view
@@ -1,12 +1,12 @@ name:		    monoids-version:	    0.1.25+version:	    0.1.28 license:	    BSD3 license-file:   LICENSE author:		    Edward A. Kmett maintainer:	    Edward A. Kmett <ekmett@gmail.com> stability:	    experimental homepage:	    http://comonad.com/reader-category:	    Data+category:	    Data, Math, Numerical, Natural Language Processing, Parsing synopsis:	    Monoids, specialized containers and a general map/reduce framework description:    Monoids, specialized containers and a general map/reduce framework copyright:      (c) 2009 Edward A. Kmett@@ -69,7 +69,9 @@     Data.Ring.Module     Data.Ring.Module.AutomaticDifferentiation     Data.Ring.Semi+    Data.Ring.Semi.BitSet     Data.Ring.Semi.Near+    Data.Ring.Semi.Near.Trie     Data.Ring.Semi.Natural     Data.Ring.Semi.Ord     Data.Ring.Semi.Tropical