packages feed

container-classes (empty) → 0.0.0.0

raw patch · 4 files changed

+789/−0 lines, 4 filesdep +basesetup-changed

Dependencies added: base

Files

+ Data/Containers.hs view
@@ -0,0 +1,733 @@+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleContexts, FlexibleInstances, TypeFamilies #-}+-- TypeFamilies is only used for equality constraints++{- |+   Module      : Data.Containers+   Description : Classes for different container types+   Copyright   : Ivan Lazar Miljenovic+   License     : 3-Clause BSD-style+   Maintainer  : Ivan.Miljenovic@gmail.com++-}+module Data.Containers where++import Prelude hiding ((!!), (++), elem, enumFrom, enumFromThen, enumFromTo, enumFromThenTo, all, and, any, break, concat, concatMap, cycle, drop, dropWhile, filter, foldl, foldl1, foldr, foldr1, head, init, iterate, last, length, lines, lookup, map, mapM, mapM_, maximum, minimum, notElem, null, or, product, repeat, replicate, reverse, scanl, scanl1, scanr, scanr1, sequence, sequence_, span, splitAt, sum, tail, take, takeWhile, unlines, unwords, unzip, unzip3, words, zip, zip3, zipWith, zipWith3, fmap)++import qualified Prelude+import Data.Char(isSpace)+import qualified Data.List as List+import Data.Maybe(fromMaybe)+import Data.Monoid+import Control.Monad(liftM2)++infixl 9  !!+infix  4 `elem`, `notElem`++-- | 'Container's are data-types that store values.  No restriction is+--   placed on /how/ they store these values, though there may be+--   restrictions on some methods if a 'Container' is also an instance+--   of a sub-class of 'Container'.+--+--   Minimum required implementation:+--+--     * 'null'+--+--     * 'insert'+--+--     * 'fold' or 'splitElem'+class (Monoid c) => Container c v | c -> v where+  -- | Test whether a 'Container' is empty.+  null :: c -> Bool++  -- | Create a singleton 'Container';+  --   i.e. @'size' ('singleton' x) == 1@).+  singleton   :: v -> c+  singleton v = build ($v)++  -- | Add a value to the 'Container'.  If this is also a 'Sequence',+  --   then it should be a \"'cons'\" operation (i.e. insert the value+  --   at the beginning of the 'Sequence').+  insert :: v -> c -> c++  -- | The container membership predicate, usually written in infix+  --   form, e.g., @v `elem` c@.+  elem :: (Eq v) => v -> c -> Bool+  elem = any . (==)++  -- | The negated version of 'elem'.+  notElem   :: (Eq v) => v -> c -> Bool+  notElem v = not . elem v++  -- | Delete the first value of the 'Container' that matches the+  --   predicate.+  delete   :: (Eq v) => v -> c -> c+  delete v = snd . fold delete' (False, empty)+    where+      delete' v' (False,c') | v' == v = (True, c')+      delete' v' (flag, c') = (flag, v' `insert` c')++  -- | Delete all values in the 'Container' that match the predicate.+  deleteAll   :: (Eq v) => v -> c -> c+  deleteAll v = filter (/=v)++  -- | When applied to a predicate and a 'Container', 'filter' returns+  --   the 'Container' containing just those elements that satisfy the+  --   predicate (preserving order where applicable).+  filter     :: (v -> Bool) -> c -> c+  filter p c = build (\ ins nil ->+                       fold (\ v c' -> if p v then v `ins` c' else c') nil c+                     )++  -- | Applied to a binary operator, a starting value and a+  --   'Container', reduce the 'Container' using the binary operator.+  --   For 'Sequence' instances, this should be a right fold.+  fold       :: (v -> a -> a) -> a -> c -> a+  fold f s c = case splitElem c of+                 Nothing -> s+                 Just (v,c') -> f v $ fold f s c'++  -- | A variant of 'fold' with no starting value, and thus must be+  --   applied to non-empty 'Container's.+  fold1   :: (v -> v -> v) -> c -> v+  fold1 f = fromMaybe err . fold f' Nothing+    where+      err = error "Container.fold1: empty container"+      f' v Nothing   = Just v+      f' v (Just v') = Just $ f v v'++  -- | Returns the size of the 'Container'.+  genericSize :: (Num n) => c -> n+  genericSize = fold (const (($!) (+1))) 0++  -- | Returns the size of the 'Container' as an 'Int'.  Typically+  --   more efficient than 'genericSize'.+  size :: c -> Int+  size = genericSize++  partition   :: (v -> Bool) -> c -> (c,c)+  partition p = fold select (empty, empty)+    where+      select v ~(ts,fs) | p v       = (v `insert` ts, fs)+                        | otherwise = (ts, v `insert` fs)++  -- | Applied to a predicate and a 'Container', 'all' determines if+  --   all elements of the 'Container' satisfy the predicate.+  all   :: (v -> Bool) -> c -> Bool+  all p = fold ((&&) . p) True++  -- | Returns the conjunction of a 'Container' containing Boolean+  --   values.  For the result to be 'True', the 'Container' must be+  --   finite; 'False', however, results from a 'False' value+  --   occurring within a finite position within the order utilised by+  --   'fold'.+  and :: (v ~ Bool) => c -> Bool+  and = fold (&&) True++  -- | Applied to a predicate and a 'Container', 'any' determines if+  --   any element of the 'Container' satisfies the predicate.+  any   :: (v -> Bool) -> c -> Bool+  any p = fold ((||) . p) True++  -- | Returns the disjunction of a 'Container' containing Boolean+  --   values.  For the result to be 'False', the 'Container' must be+  --   finite; 'True', however, results from a 'True' value+  --   occurring within a finite position within the order utilised by+  --   'fold'.+  or :: (v ~ Bool) => c -> Bool+  or = fold (||) False++  -- | Computes the product of a finite 'Container' of numbers.+  product :: (Num v) => c -> v+  product = fold (*) 1++  -- | Computes the sum of a finite 'Container' of numbers.+  sum :: (Num v) => c -> v+  sum = fold (+) 0++  -- | A type-preserving mapping function, where the resulting+  --   'Container' is obtained by applying the provided function on+  --   every element of the 'Container'.  For instances of 'CFunctor',+  --   @'rigidMap' = 'map'@ suffices.+  rigidMap     :: (v -> v) -> c -> c+  rigidMap f c = build (\ins nil -> fold (ins . f) nil c)++  -- | An inverse to 'insert'.  Should obey the following:+  --+  --   * @isNothing ('splitElem' c) == 'null' c@+  --+  --   * If @'splitElem' c = 'Just' (v,c')@, then @c == v `'insert'` c'@.+  --+  --   * If @c@ is an instance of 'Sequence', then the returned value+  --     should be the first one.+  splitElem :: c -> Maybe (v, c)+  splitElem = fold getFirst Nothing+        where+          getFirst v Nothing         = Just (v, empty)+          getFirst v (Just (v', c')) = Just (v', v `insert` c')++  -- | Returns the maximum value of a non-empty, finite 'Container'.+  maximum :: (Ord v) => c -> v+  maximum c+    | null c    = error "Container.maximum: empty container"+    | otherwise = fold1 max c++  -- | Returns the minimum value of a non-empty, finite 'Container'.+  minimum :: (Ord v) => c -> v+  minimum c+    | null c    = error "Container.minimum: empty container"+    | otherwise = fold1 min c++build   :: (Container c v) => ((v -> c -> c) -> c -> c) -> c+build f = f insert empty++-- | An alias for 'mempty'; constructs an empty 'Container'.+empty :: (Container c v) => c+empty = mempty++-- | An alias for 'mappend'; combines two 'Container's.  For instances+--   of 'Sequence' this should be an @append@ operation.+(++) :: (Container c v) => c -> c -> c+(++) = mappend++-- | Concatenate all the inner 'Container's together.+concat :: (Container o i, Container i v) => o -> i+concat = fold (++) empty++-- | Map a function over a 'Container' and concatenate the results.+--   Note that the types of the initial and final 'Container's do not+--   have to be the same.+concatMap     :: (Container f fv, Container t tv) => (fv -> t) -> f -> t+concatMap f c = build (\ ins nil -> fold ((++) . f) nil c)++-- | Convert one 'Container' to another.  If they are both+--   'Sequence's, then ordering is preserved.+convertContainer :: (Container f v, Container t v) => f -> t+convertContainer = convertContainerBy id++-- | Convert one 'Container' to another by utilising a mapping+--   function.  If they are both 'Sequence's, then ordering is+--   preserved.+convertContainerBy     :: (Container f fv, Container t tv)+                          => (fv -> tv) -> f -> t+convertContainerBy f c = build (\ ins nil -> fold (ins . f) nil c)++-- | Denotes 'Container's that have kind @* -> *@ and can thus have+--   more than one possible type of value stored within them.+class (Container (c a) a) => CFunctor c a where+  -- | Apply the provided function on every element of the 'Container'.+  map :: (CFunctor c b) => (a -> b) -> c a -> c b+  map = convertContainerBy++-- | Evaluate each action in the 'Container' and collect the results.+--   The order the actions are evaluated in are determined by the+--   corresponding 'fold' definition.+sequence :: (Monad m, CFunctor c a, CFunctor c (m a)) => c (m a) -> m (c a)+sequence = mapM id++-- | Evaluate each action in the 'Container' and discard the results.+--   The order the actions are evaluated in are determined by the+--   corresponding 'fold' definition.+sequence_ :: (Monad m, Container c (m a)) => c -> m ()+sequence_ = fold (>>) (return ())+-- Can't use "mapM_ id" as it requires an internal container and thus+-- constrains the type more.++-- | Apply the monadic mapping function to all the elements of the+--   'Container, and then evaluate the actions and collect the+--   results.  The order the actions are evaluated in are determined+--   by the corresponding 'fold' definition.+mapM   :: (Monad m, CFunctor c a, CFunctor c b) => (a -> m b) -> c a -> m (c b)+mapM f = fold (liftM2 insert . f) (return empty)+-- By not using sequence, we remove the requirement of the extra internal constraint++-- | Apply the monadic mapping function to all the elements of the+--   'Container, and then evaluate the actions and discard the+--   results.  The order the actions are evaluated in are determined+--   by the corresponding 'fold' definition.+mapM_   :: (Monad m, CFunctor c a) => (a -> m b) -> c a -> m ()+mapM_ f = fold ((>>) . f) (return ())++-- -----------------------------------------------------------------------------++-- | 'Sequence's are linear 'Container's with explicit left (start)+--   and right (end) ends.  As such, it is possible to append/traverse+--   from either end.+--+--   All methods have default stand-alone definitions, and thus no+--   explicit method definitions are required for instances.+class (Container c v) => Sequence c v where+  -- | Append the value to the end of the 'Sequence'.+  snoc     :: c -> v -> c+  snoc c v = c ++ singleton v++  -- | Applied to a binary operator, a starting value and a+  --   'Sequence', reduce the 'Sequence' using the binary operator+  --   from left to right.+  --+  --   The default definition is modelled after 'Data.List.foldl''+  --   rather than 'Data.List.foldl'.+  foldl :: (b -> v -> b) -> b -> c -> b+  foldl f s c = case viewL c of+                  Nothing -> s+                  Just (v,c') -> let s' = f s v+                                 in s' `seq` foldl f s' c'++  -- | A variant of 'foldl' with no starting value, and thus must be+  --   applied to non-empty 'Sequences's.+  foldl1   :: (v -> v -> v) -> c -> v+  foldl1 f = fromMaybe err . foldl f' Nothing+    where+      err = error "Sequence.foldl1: empty sequence"+      f' Nothing   v = Just v+      f' (Just v') v = Just $ f v' v++  -- | An inverse to 'snoc' (equivalent to @('init' xs, 'last xs')@+  --   for non-empty 'Sequence's).  Should obey the following:+  --+  --   * @isNothing ('viewR' xs) == 'null' xs@+  --+  --   * If @'viewR' xs = 'Just' (x,xs')@, then @xs == xs' `'snoc'` x@.+  viewR :: c -> Maybe (v, c)+  viewR = foldl getLast Nothing+    where+      getLast Nothing         v = Just (v, empty)+      getLast (Just (v', c')) v = Just (v', c' `snoc` v)++  -- | The first element of a non-empty 'Sequence'.+  head :: (Sequence c v) => c -> v+  head = maybe err fst . viewL+    where+      err = error "Sequence.head: empty sequence"++  -- | Everything except the first element of a non-empty 'Sequence'.+  --   Consider instead using 'drop 1'.+  tail :: (Sequence c v) => c -> c+  tail = maybe err snd . viewL+    where+      err = error "Sequence.tail: empty sequence"++  -- | The last element of a non-empty 'Sequence'.+  last :: (Sequence c v) => c -> v+  last = maybe err fst . viewR+    where+      err = error "Sequence.last: empty sequence"++  -- | Everything except the last value of a non-empty 'Sequence'.+  init :: (Sequence c v) => c -> c+  init = maybe err snd . viewR+    where+      err = error "Sequence.init: empty sequence"++  -- | Return the first @n@ elements of a 'Sequence', or the entire+  --   'Sequence' if its 'length' is less than @n@.+  genericTake   :: (Integral n) => n -> c -> c+  genericTake l = go l . viewL+    where+      go n _ | n <= 0  = empty+      go _ Nothing     = empty+      go n (Just(v,c')) = v `cons` go (n-1) (viewL c')++  -- | A variant of 'genericTake' where @n@ has to be an 'Int', and is+  --   usually more efficient.+  take :: Int -> c -> c+  take = genericTake++  -- | When applied to a predicate @p@ and a 'Sequence' @xs@, returns+  --   the longest prefix (possibly empty) of @xs@ of elements that+  --   satisfy @p@.+  takeWhile   :: (v -> Bool) -> c -> c+  takeWhile p = go . viewL+    where+      go Nothing = empty+      go (Just(v,c))+        | p v       = v `cons` go (viewL c)+        | otherwise = empty++  -- | @'dropWhile' p xs@ returns the suffix remaining after+  --   @'takeWhile' p xs@.+  dropWhile     :: (v -> Bool) -> c -> c+  dropWhile p c = build (go (viewL c))+    where+      go Nothing     _   nil = nil+      go (Just(v,c)) ins nil+        | p v       = go (viewL c) ins nil+        | otherwise = v `ins` c++  -- | @'genericDrop' n xs@ returns the suffix of @xs@ after the first+  --   @n@ elements, or 'empty' if @n > 'length' xs@.+  genericDrop     :: (Integral n) => n -> c -> c+  genericDrop l c = build (go l (viewL c))+    where+      go _ Nothing     _   nil = nil+      go n (Just(_,c)) ins nil+        | n <= 0    = nil+        | otherwise = go (n-1) (viewL c) ins nil++  -- | A variant of 'genericDrop' where @n@ has to be an 'Int', and is+  --   usually more efficient.+  drop :: Int -> c -> c+  drop = genericDrop++  -- | @'reverse' xs@ returns the elements of @xs@ in reverse order.+  --   @xs@ must be finite.+  reverse   :: c -> c+  reverse c = build (\ ins nil -> foldl (flip ins) nil c)++  -- | When applied to a predicate @p@ and a 'Sequence' @xs@, returns+  --   a tuple where first element is longest prefix (possibly empty)+  --   of @xs@ of elements that satisfy p and second element is the+  --   remainder of the 'Sequence'.+  span   :: (v -> Bool) -> c -> (c,c)+  span p = go . viewL+    where+      go Nothing = (empty, empty)+      go (Just(v,c))+        | p v       = let (t,f) = go (viewL c) in (v `cons` t, f)+        | otherwise = (empty, v `cons` c)++  -- | When applied to a predicate @p@ and a 'Sequence' @xs@, returns+  --   a tuple where first element is longest prefix (possibly empty)+  --   of @xs@ of elements that /do not satisfy/ p and second element+  --   is the remainder of the 'Sequence'.+  --+  --    @'break' p@ is equivalent to @'span' ('not' . p)@.+  break :: (v -> Bool) -> c -> (c,c)+  break = span . (not .)++  -- | @'genericSplitAt' n xs@ returns a tuple where the first element+  --   is the prefix of 'length' @n@ of @xs@ and the second element is+  --   the rest of the 'Sequence'.  It is equivalent to+  --   @('genericTake' n xs, 'genericDrop' n xs)@.+  genericSplitAt   :: (Integral n) => n -> c -> (c,c)+  genericSplitAt n c = (genericTake n c, genericDrop n c)++  -- | A variant of 'genericSplitAt' where @n@ has to be an 'Int', and+  --   is usually more efficient.+  splitAt     :: Int -> c -> (c,c)+  splitAt n c = (take n c, drop n c)++  -- | @'genericReplicate' n x@ is a 'Sequence' of length @n@ where+  --   every element is @x@.+  genericReplicate     :: (Integral n) => n -> v -> c+  genericReplicate l v = build (go l)+    where+      go n _   nil | n <= 0 = nil+      go n ins nil = v `ins` go (n-1) ins nil++  -- | A variant of 'genericReplicate' where @n@ has to be an 'Int',+  --   and is usually more efficient.+  replicate :: Int -> v -> c+  replicate = genericReplicate++  -- | 'lines' breaks a string up into a 'Sequence' of 'Strings' at+  --   newline characters. The resulting 'Strings' do not contain+  --   newlines.+  lines :: (v ~ String) => String -> c+  lines = build . go+    where+      go "" _   nil = nil+      go s  ins nil = let (l, s') = Prelude.break (== '\n') s+                      in l `ins` case s' of+                                   ""      -> nil+                                   (_:s'') -> go s'' ins nil++  -- | 'unlines' is an inverse operation to 'lines'. It joins lines,+  --   after appending a terminating newline to each.+  unlines :: (v ~ String) => c -> String+  unlines = go . viewL+    where+      go Nothing = ""+      go (Just(l,ls)) = l Prelude.++ '\n' : go (viewL ls)++  -- | 'words' breaks a 'String' up into a 'Sequence' of words, which+  --   were delimited by white space.+  words :: (v ~ String) => String -> c+  words = build . go+    where+      go s ins nil = case Prelude.dropWhile isSpace s of+                       "" -> nil+                       s' -> let (w,s'') = Prelude.break isSpace s'+                             in w `ins` go s'' ins nil++  -- | 'unwords' is an inverse operation to 'words'. It joins words+  --   with separating spaces.+  unwords :: (v ~ String) => c -> String+  unwords = go . viewL+    where+      go Nothing       = ""+      go (Just(fw,ws)) = go' fw $ viewL ws+        where+          go' w Nothing        = w+          go' w (Just(w',ws')) = w Prelude.++ ' ' : go' w' (viewL ws')+++buildL   :: (Sequence c v) => ((c -> v -> c) -> c -> c) -> c+buildL f = f snoc empty++-- | An alias for 'insert' for 'Sequence's.+cons :: (Sequence c v) => v -> c -> c+cons = insert++-- | An alias for 'genericSize' for 'Sequence's.+genericLength :: (Sequence c v, Integral n) => c -> n+genericLength = genericSize++-- | An alias for 'size' for 'Sequence's.+length :: (Sequence c v) => c -> Int+length = size++-- | An alias for 'fold' for 'Seuquence's.+foldr :: (Sequence c v) => (v -> a -> a) -> a -> c -> a+foldr = fold++-- | An alias for 'fold1' for 'Seuquence's.+foldr1 :: (Sequence c v) => (v -> v -> v) -> c -> v+foldr1 = fold1++-- | An alias for 'splitElem' for 'Seuquence's.+viewL :: (Sequence c v) => c -> Maybe (v,c)+viewL = splitElem++-- | 'Sequence' index (subscript) operator, starting from 0.  Will+--    throw an 'error' if the index is negative or larger than the+--    length of the 'Sequence'.+(!!) :: (Sequence c v) => c -> Int -> v+_ !! n | n < 0 = error "Sequence.(!!): negative index"+c !! n = maybe err fst . viewL $ drop (n-1) c+  where+    err = error "Sequence.(!!): index too large"++-- | Represents 'Sequence's that are also instances of 'CFunctor'.+--   All methods have default definitions.+class (Sequence (c a) a, CFunctor c a) => SFunctor c a where+  scanl     :: (SFunctor c b) => (b -> a -> b) -> b -> c a -> c b+  scanl f b =  build . go b+    where+      go v c ins nil = v `ins`+                       case viewL c of+                         Nothing -> nil+                         Just (v',c') -> go (f v v') c ins nil++  scanl1   :: (a -> a -> a) -> c a -> c a+  scanl1 f = maybe (build (const id)) (uncurry (scanl f)) . viewL++  scanr     :: (SFunctor c b) => (a -> b -> b) -> b -> c a -> c b+  scanr f b = build . go . viewL+    where+      go Nothing     _   _   = singleton b+      go (Just(v,c)) ins nil = f v (head c') `ins` c'+        where+          c' = go (viewL c) ins nil++  scanr1   :: (a -> a -> a) -> c a -> c a+  scanr1 f = maybe (build (const id)) (uncurry (scanr f)) . viewL++  zipWith         :: (SFunctor c b, SFunctor c d)+                     => (a -> b -> d) -> c a -> c b -> c d+  zipWith f ca cb = build $ wrap ca cb+    where+      wrap ca' cb' = go (viewL ca') (viewL cb')+      go (Just(a,ca')) (Just(b,cb')) ins nil = f a b `ins` wrap ca' cb' ins nil+      go _             _             _   nil = nil++  zip :: (SFunctor c b, SFunctor c (a,b)) => c a -> c b -> c (a,b)+  zip = zipWith (,)++  unzip :: (SFunctor c b, SFunctor c (a,b)) => c (a,b) -> (c a, c b)+  unzip = fold f (empty,empty)+    where+      f (a,b) ~(ca,cb) = (a `cons` ca, b `cons` cb)++  zipWith3            :: (SFunctor c b, SFunctor c d, SFunctor c e)+                         => (a -> b -> d -> e) -> c a -> c b -> c d -> c e+  zipWith3 f ca cb cd = build $ wrap ca cb cd+    where+      wrap ca' cb' cd' = go (viewL ca') (viewL cb') (viewL cd')+      go (Just(a,ca')) (Just(b,cb')) (Just(d,cd')) ins nil = f a b d+                                                             `ins`+                                                             wrap ca' cb' cd' ins nil+      go _             _             _             _   nil = nil++  zip3 :: (SFunctor c b, SFunctor c d, SFunctor c (a,b,d))+         => c a -> c b -> c d -> c (a,b,d)+  zip3 = zipWith3 (,,)++  unzip3 :: (SFunctor c b, SFunctor c d, SFunctor c (a,b,d))+            => c (a,b,d) -> (c a, c b, c d)+  unzip3 = fold f (empty,empty,empty)+    where+      f (a,b,d) ~(ca,cb,cd) = (a `cons` ca, b `cons` cb, d `cons` cd)++-- -----------------------------------------------------------------------------++-- | Represents 'Sequence's that may be infinite in length.  All+--   methods have default definitions.+class (Sequence c v) => Stream c v where+  -- | @'repeat' x@ is an infinite 'Stream', with @x@ the value of+  --   every element.+  repeat   :: v -> c+  repeat v = v `cons` repeat v++  -- | 'cycle' ties a finite 'Stream' into a circular one, or+  --   equivalently, the infinite repetition of the original 'Stream'.+  --   It is the identity on infinite 'Stream's.+  cycle :: c -> c+  cycle = checkNull+    where+      checkNull c+        | null c    = error "Stream.cycle: empty stream"+        | otherwise = go c+      go c = c ++ go c++  -- | @'iterate' f x@ returns an infinite 'Stream' of repeated+  --   applications of @f@ to @x@:+  --+  --   > iterate f x = x `cons` f x `cons` f (f x) `cons` ...+  iterate   :: (v -> v) -> v -> c+  iterate f = build . go+    where+      go x ins nil = x `ins` go (f x) ins nil++-- | A wrapper around 'Prelude.enumFrom'.+enumFrom :: (Enum a, Stream c a) => a -> c+enumFrom = convertContainer . Prelude.enumFrom++-- | A wrapper around 'Prelude.enumFromThen'.+enumFromThen      :: (Enum a, Stream c a) => a -> a -> c+enumFromThen f th = convertContainer $ Prelude.enumFromThen f th++-- | A wrapper around 'Prelude.enumFromThenTo'.+enumFromThenTo        :: (Enum a, Sequence c a) => a -> a -> a -> c+enumFromThenTo f th t = convertContainer $ Prelude.enumFromThenTo f th t++-- | A wrapper around 'Prelude.enumFromTo'.+enumFromTo     :: (Enum a, Sequence c a) => a -> a -> c+enumFromTo f t = convertContainer $ Prelude.enumFromTo f t++-- -----------------------------------------------------------------------------++instance Container [a] a where+  null = Prelude.null++  -- Use default to have build be used+  -- singleton = (:[])++  insert = (:)++  elem = Prelude.elem++  notElem = Prelude.notElem++  delete = List.delete++  -- No pre-defined deleteAll equivalent++  filter = Prelude.filter++  fold = Prelude.foldr++  fold1 = Prelude.foldr1++  genericSize = List.genericLength++  size = Prelude.length++  partition = List.partition++  all = Prelude.all++  and = Prelude.and++  any = Prelude.any++  or = Prelude.or++  product = Prelude.product++  sum = Prelude.sum++  rigidMap = map++  splitElem []     = Nothing+  splitElem (a:as) = Just (a,as)++  maximum = Prelude.maximum++  minimum = Prelude.minimum++instance CFunctor [] a where+  map = Prelude.map++instance Sequence [a] a where+  -- snoc can stay as is++  foldl = List.foldl'++  foldl1 = List.foldl1'++  -- Get the laziness into it+  viewR [] = Nothing+  viewR as = Just (last as, init as)++  head = Prelude.head++  tail = Prelude.tail++  last = Prelude.last++  init = Prelude.init++  genericTake = List.genericTake++  take = Prelude.take++  takeWhile = Prelude.takeWhile++  dropWhile = Prelude.dropWhile++  genericDrop = List.genericDrop++  drop = Prelude.drop++  reverse = Prelude.reverse++  span = Prelude.span++  break = Prelude.break++  genericSplitAt = List.genericSplitAt++  splitAt = Prelude.splitAt++  genericReplicate = List.genericReplicate++  replicate = Prelude.replicate++  lines = Prelude.lines++  unlines = Prelude.unlines++  words = Prelude.words++  unwords = Prelude.unwords++instance SFunctor [] a where+  scanl = Prelude.scanl++  scanl1 = Prelude.scanl1++  scanr = Prelude.scanr++  scanr1 = Prelude.scanr1++  zip = Prelude.zip++  zipWith = Prelude.zipWith++  unzip = Prelude.unzip++  zip3 = Prelude.zip3++  zipWith3 = Prelude.zipWith3++  unzip3 = Prelude.unzip3
+ LICENSE view
@@ -0,0 +1,33 @@+Copyright (c) 2010, Ivan Lazar Miljenovic++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * 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.++    * Neither the name of Ivan Lazar Miljenovic nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"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 COPYRIGHT+OWNER 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.++This library uses code based upon that of the Glasgow Haskell Compiler+(GHC): http://haskell.org/ghc/
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ container-classes.cabal view
@@ -0,0 +1,21 @@+Name:                container-classes+Version:             0.0.0.0+Synopsis:            Generic classes for interacting with different container types+Description:         Allow users of your library to choose which data+                     structure they want to use rather than+                     constraining them to whatever you chose at the+                     time.+License:             BSD3+License-file:        LICENSE+Author:              Ivan Lazar Miljenovic+Maintainer:          Ivan.Miljenovic@gmail.com+Copyright:           Ivan Lazar Miljenovic+Category:            Data Structures+Build-type:          Simple+-- Extra-source-files:+Cabal-Version:       >=1.2+++Library+  Exposed-modules:     Data.Containers+  Build-Depends:       base < 5