-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A library of efficent, purely-functional data structures (API) -- -- Edison is a library of purely functional data structures written by -- Chris Okasaki. It is named after Thomas Alva Edison and for the -- mnemonic value EDiSon (Efficent Data Structures). Edison provides -- several families of abstractions, each with multiple implementations. -- The main abstractions provided by Edison are: Sequences such as -- stacks, queues, and dequeues; Collections such as sets, bags and -- heaps; and Associative Collections such as finite maps and priority -- queues where the priority and element are distinct. @package EdisonAPI @version 1.3 -- | This module is a central depository of common definitions used -- throughout Edison. module Data.Edison.Prelude -- | This class represents hashable objects. If obeys the following -- invariant: -- --
--   forall x,y :: a. (x == y) implies (hash x == hash y)
--   
class Eq a => Hash a hash :: Hash a => a -> Int -- | This class represents hashable objects where the hash function is -- unique (injective). There are no new methods, just a stronger -- invariant: -- --
--   forall x,y :: a. (x == y) iff (hash x == hash y)
--   
class Hash a => UniqueHash a -- | This class represents hashable objects where the hash is reversible. -- --
--   forall x :: a. unhash (hash x) == x
--   
-- -- Note that: -- --
--   hash (unhash i) == i
--   
-- -- does not necessarily hold because unhash is not necessarily -- defined for all i, only for all i in the range of -- hash. class UniqueHash a => ReversibleHash a unhash :: ReversibleHash a => Int -> a -- | This class represents a quantity that can be measured. It is -- calculated by an associative function with a unit (hence the -- Monoid superclass, and by a function which gives the -- measurement for an individual item. Some datastructures are able to -- speed up the calculation of a measure by caching intermediate values -- of the computation. class (Monoid v) => Measured v a | a -> v measure :: Measured v a => a -> v -- | The sequence abstraction is usually viewed as a hierarchy of ADTs -- including lists, queues, deques, catenable lists, etc. However, such a -- hierarchy is based on efficiency rather than functionality. For -- example, a list supports all the operations that a deque supports, -- even though some of the operations may be inefficient. Hence, in -- Edison, all sequence data structures are defined as instances of the -- single Sequence class: -- --
--   class (Functor s, MonadPlus s) => Sequence s
--   
-- -- All sequences are also instances of Functor, Monad, and -- MonadPlus. In addition, all sequences are expected to be -- instances of Eq, Show, and Read, although -- this is not enforced. -- -- We follow the naming convention that every module implementing -- sequences defines a type constructor named Seq. -- -- For each method the "default" complexity is listed. Individual -- implementations may differ for some methods. The documentation for -- each implementation will list those methods for which the running time -- differs from these. -- -- A description of each Sequence function appears below. In most cases -- psudeocode is also provided. Obviously, the psudeocode is illustrative -- only. -- -- Sequences are represented in psudecode between angle brackets: -- --
--   <x0,x1,x2...,xn-1>
--   
-- -- Such that x0 is at the left (front) of the sequence and -- xn-1 is at the right (rear) of the sequence. module Data.Edison.Seq -- | Return the result of applying a function to every element of a -- sequence. Identical to fmap from Functor. -- --
--   map f <x0,...,xn-1> = <f x0,...,f xn-1>
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f map :: Sequence s => (a -> b) -> s a -> s b -- | Create a singleton sequence. Identical to return from -- Monad. -- --
--   singleton x = <x>
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( 1 ) singleton :: Sequence s => a -> s a -- | Apply a sequence-producing function to every element of a sequence and -- flatten the result. concatMap is the bind (>>=) -- operation of from Monad with the arguments in the reverse -- order. -- --
--   concatMap f xs = concat (map f xs)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n + m ) where n is the -- length of the input sequence, m is the length of the output -- sequence, and t is the running time of f concatMap :: Sequence s => (a -> s b) -> s a -> s b -- | The empty sequence. Identical to mzero from -- MonadPlus. -- --
--   empty = <>
--   
-- -- This function is always unambiguous. -- -- Default running time: O( 1 ) empty :: Sequence s => s a -- | Append two sequence, with the first argument on the left and the -- second argument on the right. Identical to mplus from -- MonadPlus. -- --
--   append <x0,...,xn-1> <y0,...,ym-1> = <x0,...,xn-1,y0,...,ym-1>
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n1 ) append :: Sequence s => s a -> s a -> s a -- | The Sequence class defines an interface for datatypes which -- implement sequences. A description for each function is given below. class (Functor s, MonadPlus s) => Sequence s -- | Add a new element to the front/left of a sequence -- --
--   lcons x <x0,...,xn-1> = <x,x0,...,xn-1>
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( 1 ) lcons :: Sequence s => a -> s a -> s a -- | Add a new element to the right/rear of a sequence -- --
--   rcons x <x0,...,xn-1> = <x0,...,xn-1,x>
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) rcons :: Sequence s => a -> s a -> s a -- | Convert a list into a sequence -- --
--   fromList [x0,...,xn-1] = <x0,...,xn-1>
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) fromList :: Sequence s => [a] -> s a -- | Create a sequence containing n copies of the given element. -- Return empty if n<0. -- --
--   copy n x = <x,...,x>
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) copy :: Sequence s => Int -> a -> s a -- | Separate a sequence into its first (leftmost) element and the -- remaining sequence. Calls fail if the sequence is empty. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( 1 ) lview :: (Sequence s, Monad m) => s a -> m (a, s a) -- | Return the first element of a sequence. Signals an error if the -- sequence is empty. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( 1 ) lhead :: Sequence s => s a -> a -- | Returns the first element of a sequence. Calls fail if the -- sequence is empty. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( 1 ) lheadM :: (Sequence s, Monad m) => s a -> m a -- | Delete the first element of the sequence. Signals error if sequence is -- empty. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( 1 ) ltail :: Sequence s => s a -> s a -- | Delete the first element of the sequence. Calls fail if the -- sequence is empty. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( 1 ) ltailM :: (Sequence s, Monad m) => s a -> m (s a) -- | Separate a sequence into its last (rightmost) element and the -- remaining sequence. Calls fail if the sequence is empty. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) rview :: (Sequence s, Monad m) => s a -> m (a, s a) -- | Return the last (rightmost) element of the sequence. Signals error if -- sequence is empty. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) rhead :: Sequence s => s a -> a -- | Returns the last element of the sequence. Calls fail if the -- sequence is empty. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) rheadM :: (Sequence s, Monad m) => s a -> m a -- | Delete the last (rightmost) element of the sequence. Signals an error -- if the sequence is empty. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) rtail :: Sequence s => s a -> s a -- | Delete the last (rightmost) element of the sequence. Calls fail -- of the sequence is empty -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) rtailM :: (Sequence s, Monad m) => s a -> m (s a) -- | Returns True if the sequence is empty and False -- otherwise. -- --
--   null <x0,...,xn-1> = (n==0)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( 1 ) null :: Sequence s => s a -> Bool -- | Returns the length of a sequence. -- --
--   size <x0,...,xn-1> = n
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) size :: Sequence s => s a -> Int -- | Convert a sequence to a list. -- --
--   toList <x0,...,xn-1> = [x0,...,xn-1]
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) toList :: Sequence s => s a -> [a] -- | Flatten a sequence of sequences into a simple sequence. -- --
--   concat xss = foldr append empty xss
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n + m ) where n is the -- length of the input sequence and m is length of the output -- sequence. concat :: Sequence s => s (s a) -> s a -- | Reverse the order of a sequence -- --
--   reverse <x0,...,xn-1> = <xn-1,...,x0>
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) reverse :: Sequence s => s a -> s a -- | Reverse a sequence onto the front of another sequence. -- --
--   reverseOnto <x0,...,xn-1> <y0,...,ym-1> = <xn-1,...,x0,y0,...,ym-1>
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n1 ) reverseOnto :: Sequence s => s a -> s a -> s a -- | Combine all the elements of a sequence into a single value, given a -- combining function and an initial value. The order in which the -- elements are applied to the combining function is unspecified. -- fold is one of the few ambiguous sequence functions. -- -- Axioms: -- -- -- -- fold f is unambiguous iff f is -- fold-commutative. -- -- Default running type: O( t * n ) where t is the -- running tome of f. fold :: Sequence s => (a -> b -> b) -> b -> s a -> b -- | A strict variant of fold. fold' is one of the few -- ambiguous sequence functions. -- -- Axioms: -- -- -- -- fold f is unambiguous iff f is -- fold-commutative. -- -- Default running type: O( t * n ) where t is the -- running tome of f. fold' :: Sequence s => (a -> b -> b) -> b -> s a -> b -- | Combine all the elements of a non-empty sequence into a single value, -- given a combining function. Signals an error if the sequence is empty. -- -- Axioms: -- -- -- -- fold1 f is unambiguous iff f is -- fold-commutative. -- -- Default running type: O( t * n ) where t is the -- running tome of f. fold1 :: Sequence s => (a -> a -> a) -> s a -> a -- | A strict variant of fold1. -- -- Axioms: -- -- -- -- fold1' f is unambiguous iff f is -- fold-commutative. -- -- Default running time: O( t * n ) where t is the -- running time of f fold1' :: Sequence s => (a -> a -> a) -> s a -> a -- | Combine all the elements of a sequence into a single value, given a -- combining function and an initial value. The function is applied with -- right nesting. -- --
--   foldr (%) c <x0,...,xn-1> = x0 % (x1 % ( ... % (xn-1 % c)))
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f foldr :: Sequence s => (a -> b -> b) -> b -> s a -> b -- | Strict variant of foldr. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f foldr' :: Sequence s => (a -> b -> b) -> b -> s a -> b -- | Combine all the elements of a sequence into a single value, given a -- combining function and an initial value. The function is applied with -- left nesting. -- --
--   foldl (%) c <x0,...,xn-1> = (((c % x0) % x1) % ... ) % xn-1
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f foldl :: Sequence s => (b -> a -> b) -> b -> s a -> b -- | Strict variant of foldl. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f foldl' :: Sequence s => (b -> a -> b) -> b -> s a -> b -- | Combine all the elements of a non-empty sequence into a single value, -- given a combining function. The function is applied with right -- nesting. Signals an error if the sequence is empty. -- --
--   foldr1 (+) <x0,...,xn-1>
--     | n==0 = error "ModuleName.foldr1: empty sequence"
--     | n>0  = x0 + (x1 + ... + xn-1)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f foldr1 :: Sequence s => (a -> a -> a) -> s a -> a -- | Strict variant of foldr1. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f foldr1' :: Sequence s => (a -> a -> a) -> s a -> a -- | Combine all the elements of a non-empty sequence into a single value, -- given a combining function. The function is applied with left nesting. -- Signals an error if the sequence is empty. -- --
--   foldl1 (+) <x0,...,xn-1>
--    | n==0 = error "ModuleName.foldl1: empty sequence"
--    | n>0  = (x0 + x1) + ... + xn-1
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f foldl1 :: Sequence s => (a -> a -> a) -> s a -> a -- | Strict variant of foldl1. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f foldl1' :: Sequence s => (a -> a -> a) -> s a -> a -- | See reduce1 for additional notes. -- --
--   reducer f x xs = reduce1 f (cons x xs)
--   
-- -- Axioms: -- -- -- -- reducer f is unambiguous iff f is an associative -- function. -- -- Default running time: O( t * n ) where t is the -- running time of f reducer :: Sequence s => (a -> a -> a) -> a -> s a -> a -- | Strict variant of reducer. -- -- See reduce1 for additional notes. -- -- Axioms: -- -- -- -- reducer' f is unambiguous iff f is an associative -- function. -- -- Default running time: O( t * n ) where t is the -- running time of f reducer' :: Sequence s => (a -> a -> a) -> a -> s a -> a -- | See reduce1 for additional notes. -- --
--   reducel f x xs = reduce1 f (rcons x xs)
--   
-- -- Axioms: -- -- -- -- reducel f is unambiguous iff f is an associative -- function. -- -- Default running time: O( t * n ) where t is the -- running time of f reducel :: Sequence s => (a -> a -> a) -> a -> s a -> a -- | Strict variant of reducel. -- -- See reduce1 for additional notes. -- -- Axioms: -- -- -- -- reducel' f is unambiguous iff f is an associative -- function. -- -- Default running time: O( t * n ) where t is the -- running time of f reducel' :: Sequence s => (a -> a -> a) -> a -> s a -> a -- | A reduce is similar to a fold, but combines elements in a balanced -- fashion. The combining function should usually be associative. If the -- combining function is associative, the various reduce functions yield -- the same results as the corresponding folds. -- -- What is meant by "in a balanced fashion"? We mean that reduce1 (%) -- <x0,x1,...,xn-1> equals some complete parenthesization of -- x0 % x1 % ... % xn-1 such that the nesting depth of -- parentheses is O( log n ). The precise shape of this -- parenthesization is unspecified. -- --
--   reduce1 f <x> = x
--   reduce1 f <x0,...,xn-1> =
--       f (reduce1 f <x0,...,xi>) (reduce1 f <xi+1,...,xn-1>)
--   
-- -- for some i such that 0 <= i && i < n-1 -- -- -- Although the exact value of i is unspecified it tends toward -- n/2 so that the depth of calls to f is at most -- logarithmic. -- -- Note that reduce* are some of the only sequence operations -- for which different implementations are permitted to yield different -- answers. Also note that a single implementation may choose different -- parenthisizations for different sequences, even if they are the same -- length. This will typically happen when the sequences were constructed -- differently. -- -- The canonical applications of the reduce functions are algorithms like -- merge sort where: -- --
--   mergesort xs = reducer merge empty (map singleton xs)
--   
-- -- Axioms: -- -- -- -- reduce1 f is unambiguous iff f is an associative -- function. -- -- Default running time: O( t * n ) where t is the -- running time of f reduce1 :: Sequence s => (a -> a -> a) -> s a -> a -- | Strict variant of reduce1. -- -- Axioms: -- -- -- -- reduce1' f is unambiguous iff f is an associative -- function. -- -- Default running time: O( t * n ) where t is the -- running time of f reduce1' :: Sequence s => (a -> a -> a) -> s a -> a -- | Extract a prefix of length i from the sequence. Return -- empty if i is negative, or the entire sequence if -- i is too large. -- --
--   take i xs = fst (splitAt i xs)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( i ) take :: Sequence s => Int -> s a -> s a -- | Delete a prefix of length i from a sequence. Return the -- entire sequence if i is negative, or empty if -- i is too large. -- --
--   drop i xs = snd (splitAt i xs)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( i ) drop :: Sequence s => Int -> s a -> s a -- | Split a sequence into a prefix of length i and the remaining -- sequence. Behaves the same as the corresponding calls to take -- and drop if i is negative or too large. -- --
--   splitAt i xs
--    | i < 0  = (<>           , <x0,...,xn-1>)
--    | i < n  = (<x0,...,xi-1>, <xi,...,xn-1>)
--    | i >= n = (<x0,...,xn-1>, <>           )
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( i ) splitAt :: Sequence s => Int -> s a -> (s a, s a) -- | Extract a subsequence from a sequence. The integer arguments are -- "start index" and "length" NOT "start index" and "end index". Behaves -- the same as the corresponding calls to take and drop if -- the start index or length are negative or too large. -- --
--   subseq i len xs = take len (drop i xs)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( i + len ) subseq :: Sequence s => Int -> Int -> s a -> s a -- | Extract the elements of a sequence that satisfy the given predicate, -- retaining the relative ordering of elements from the original -- sequence. -- --
--   filter p xs = foldr pcons empty xs
--        where pcons x xs = if p x then cons x xs else xs
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of p filter :: Sequence s => (a -> Bool) -> s a -> s a -- | Separate the elements of a sequence into those that satisfy the given -- predicate and those that do not, retaining the relative ordering of -- elements from the original sequence. -- --
--   partition p xs = (filter p xs, filter (not . p) xs)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of p partition :: Sequence s => (a -> Bool) -> s a -> (s a, s a) -- | Extract the maximal prefix of elements satisfying the given predicate. -- --
--   takeWhile p xs = fst (splitWhile p xs)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of p takeWhile :: Sequence s => (a -> Bool) -> s a -> s a -- | Delete the maximal prefix of elements satisfying the given predicate. -- --
--   dropWhile p xs = snd (splitWhile p xs)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of p dropWhile :: Sequence s => (a -> Bool) -> s a -> s a -- | Split a sequence into the maximal prefix of elements satisfying the -- given predicate, and the remaining sequence. -- --
--   splitWhile p <x0,...,xn-1> = (<x0,...,xi-1>, <xi,...,xn-1>)
--     where i = min j such that p xj (or n if no such j)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of p splitWhile :: Sequence s => (a -> Bool) -> s a -> (s a, s a) -- | Test whether an index is valid for the given sequence. All indexes are -- 0 based. -- --
--   inBounds i <x0,...,xn-1> = (0 <= i && i < n)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( i ) inBounds :: Sequence s => Int -> s a -> Bool -- | Return the element at the given index. All indexes are 0 based. -- Signals error if the index out of bounds. -- --
--   lookup i xs@<x0,...,xn-1>
--     | inBounds i xs = xi
--     | otherwise = error "ModuleName.lookup: index out of bounds"
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( i ) lookup :: Sequence s => Int -> s a -> a -- | Return the element at the given index. All indexes are 0 based. Calls -- fail if the index is out of bounds. -- --
--   lookupM i xs@<x0,...,xn-1>
--     | inBounds i xs = Just xi
--     | otherwise = Nothing
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( i ) lookupM :: (Sequence s, Monad m) => Int -> s a -> m a -- | Return the element at the given index, or the default argument if the -- index is out of bounds. All indexes are 0 based. -- --
--   lookupWithDefault d i xs@<x0,...,xn-1>
--     | inBounds i xs = xi
--     | otherwise = d
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( i ) lookupWithDefault :: Sequence s => a -> Int -> s a -> a -- | Replace the element at the given index, or return the original -- sequence if the index is out of bounds. All indexes are 0 based. -- --
--   update i y xs@<x0,...,xn-1>
--     | inBounds i xs = <x0,...xi-1,y,xi+1,...,xn-1>
--     | otherwise = xs
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( i ) update :: Sequence s => Int -> a -> s a -> s a -- | Apply a function to the element at the given index, or return the -- original sequence if the index is out of bounds. All indexes are 0 -- based. -- --
--   adjust f i xs@<x0,...,xn-1>
--     | inBounds i xs = <x0,...xi-1,f xi,xi+1,...,xn-1>
--     | otherwise = xs
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( i + t ) where t is the -- running time of f adjust :: Sequence s => (a -> a) -> Int -> s a -> s a -- | Like map, but include the index with each element. All indexes -- are 0 based. -- --
--   mapWithIndex f <x0,...,xn-1> = <f 0 x0,...,f (n-1) xn-1>
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f mapWithIndex :: Sequence s => (Int -> a -> b) -> s a -> s b -- | Like foldr, but include the index with each element. All -- indexes are 0 based. -- --
--   foldrWithIndex f c <x0,...,xn-1> = 
--       f 0 x0 (f 1 x1 (... (f (n-1) xn-1 c)))
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f foldrWithIndex :: Sequence s => (Int -> a -> b -> b) -> b -> s a -> b -- | Strict variant of foldrWithIndex. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f foldrWithIndex' :: Sequence s => (Int -> a -> b -> b) -> b -> s a -> b -- | Like foldl, but include the index with each element. All -- indexes are 0 based. -- --
--   foldlWithIndex f c <x0,...,xn-1> =
--       f (...(f (f c 0 x0) 1 x1)...) (n-1) xn-1)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f foldlWithIndex :: Sequence s => (b -> Int -> a -> b) -> b -> s a -> b -- | Strict variant of foldlWithIndex. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- running time of f foldlWithIndex' :: Sequence s => (b -> Int -> a -> b) -> b -> s a -> b -- | Combine two sequences into a sequence of pairs. If the sequences are -- different lengths, the excess elements of the longer sequence is -- discarded. -- --
--   zip <x0,...,xn-1> <y0,...,ym-1> = <(x0,y0),...,(xj-1,yj-1)>
--       where j = min {n,m}
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( min( n1, n2 ) ) zip :: Sequence s => s a -> s b -> s (a, b) -- | Like zip, but combines three sequences into triples. -- --
--   zip3 <x0,...,xn-1> <y0,...,ym-1> <z0,...,zk-1> = 
--        <(x0,y0,z0),...,(xj-1,yj-1,zj-1)>
--      where j = min {n,m,k}
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( min( n1, n2, n3 ) ) zip3 :: Sequence s => s a -> s b -> s c -> s (a, b, c) -- | Combine two sequences into a single sequence by mapping a combining -- function across corresponding elements. If the sequences are of -- different lengths, the excess elements of the longer sequence are -- discarded. -- --
--   zipWith f xs ys = map (uncurry f) (zip xs ys)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * min( n1, n2 ) ) where t -- is the running time of f zipWith :: Sequence s => (a -> b -> c) -> s a -> s b -> s c -- | Like zipWith but for a three-place function and three -- sequences. -- --
--   zipWith3 f xs ys zs = map (uncurry f) (zip3 xs ys zs)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * min( n1, n2, n3 ) ) where -- t is the running time of f zipWith3 :: Sequence s => (a -> b -> c -> d) -> s a -> s b -> s c -> s d -- | Transpose a sequence of pairs into a pair of sequences. -- --
--   unzip xs = (map fst xs, map snd xs)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) unzip :: Sequence s => s (a, b) -> (s a, s b) -- | Transpose a sequence of triples into a triple of sequences -- --
--   unzip3 xs = (map fst3 xs, map snd3 xs, map thd3 xs)
--      where fst3 (x,y,z) = x
--            snd3 (x,y,z) = y
--            thd3 (x,y,z) = z
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) unzip3 :: Sequence s => s (a, b, c) -> (s a, s b, s c) -- | Map two functions across every element of a sequence, yielding a pair -- of sequences -- --
--   unzipWith f g xs = (map f xs, map g xs)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- maximum running time of f and g unzipWith :: Sequence s => (a -> b) -> (a -> c) -> s a -> (s b, s c) -- | Map three functions across every element of a sequence, yielding a -- triple of sequences. -- --
--   unzipWith3 f g h xs = (map f xs, map g xs, map h xs)
--   
-- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( t * n ) where t is the -- maximum running time of f, g, and h unzipWith3 :: Sequence s => (a -> b) -> (a -> c) -> (a -> d) -> s a -> (s b, s c, s d) -- | Semanticly, this function is a partial identity function. If the -- datastructure is infinite in size or contains exceptions or -- non-termination in the structure itself, then strict will -- result in bottom. Operationally, this function walks the datastructure -- forcing any closures. Elements contained in the sequence are -- not forced. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: O( n ) strict :: Sequence s => s a -> s a -- | Similar to strict, this function walks the datastructure -- forcing closures. However, strictWith will additionally apply -- the given function to the sequence elements, force the result using -- seq, and then ignore it. This function can be used to perform -- various levels of forcing on the sequence elements. In particular: -- --
--   strictWith id xs
--   
-- -- will force the spine of the datastructure and reduce each element to -- WHNF. -- -- Axioms: -- -- -- -- This function is always unambiguous. -- -- Default running time: unbounded (forcing element closures can take -- arbitrairly long) strictWith :: Sequence s => (a -> b) -> s a -> s a -- | A method to facilitate unit testing. Returns True if the -- structural invariants of the implementation hold for the given -- sequence. If this function returns False, it represents a bug -- in the implementation. structuralInvariant :: Sequence s => s a -> Bool -- | The name of the module implementing s. instanceName :: Sequence s => s a -> String -- | This module packages the standard prelude list type as a sequence. -- This is the baseline sequence implementation and all methods have the -- default running times listed in Data.Edison.Seq, except for the -- following two trivial operations: -- -- module Data.Edison.Seq.ListSeq type Seq a = [a] empty :: [a] singleton :: a -> [a] lcons :: a -> [a] -> [a] rcons :: a -> [a] -> [a] append :: [a] -> [a] -> [a] lview :: (Monad rm) => [a] -> rm (a, [a]) lhead :: [a] -> a lheadM :: (Monad rm) => [a] -> rm a ltail :: [a] -> [a] ltailM :: (Monad rm) => [a] -> rm [a] rview :: (Monad rm) => [a] -> rm (a, [a]) rhead :: [a] -> a rheadM :: (Monad rm) => [a] -> rm a rtail :: [a] -> [a] rtailM :: (Monad rm) => [a] -> rm [a] null :: [a] -> Bool size :: [a] -> Int concat :: [[a]] -> [a] reverse :: [a] -> [a] reverseOnto :: [a] -> [a] -> [a] fromList :: [a] -> [a] toList :: [a] -> [a] map :: (a -> b) -> [a] -> [b] concatMap :: (a -> [b]) -> [a] -> [b] fold :: (a -> b -> b) -> b -> [a] -> b fold' :: (a -> b -> b) -> b -> [a] -> b fold1 :: (a -> a -> a) -> [a] -> a fold1' :: (a -> a -> a) -> [a] -> a foldr :: (a -> b -> b) -> b -> [a] -> b foldr' :: (t -> a -> a) -> a -> [t] -> a foldl :: (b -> a -> b) -> b -> [a] -> b foldl' :: (b -> a -> b) -> b -> [a] -> b foldr1 :: (a -> a -> a) -> [a] -> a foldr1' :: (a -> a -> a) -> [a] -> a foldl1 :: (a -> a -> a) -> [a] -> a foldl1' :: (a -> a -> a) -> [a] -> a reducer :: (a -> a -> a) -> a -> [a] -> a reducer' :: (a -> a -> a) -> a -> [a] -> a reducel :: (a -> a -> a) -> a -> [a] -> a reducel' :: (a -> a -> a) -> a -> [a] -> a reduce1 :: (a -> a -> a) -> [a] -> a reduce1' :: (a -> a -> a) -> [a] -> a copy :: Int -> a -> [a] inBounds :: Int -> [a] -> Bool lookup :: Int -> [a] -> a lookupM :: (Monad m) => Int -> [a] -> m a lookupWithDefault :: a -> Int -> [a] -> a update :: Int -> a -> [a] -> [a] adjust :: (a -> a) -> Int -> [a] -> [a] mapWithIndex :: (Int -> a -> b) -> [a] -> [b] foldrWithIndex :: (Int -> a -> b -> b) -> b -> [a] -> b foldrWithIndex' :: (Enum a1, Num a1) => (a1 -> t -> a -> a) -> a -> [t] -> a foldlWithIndex :: (b -> Int -> a -> b) -> b -> [a] -> b foldlWithIndex' :: (b -> Int -> a -> b) -> b -> [a] -> b take :: Int -> [a] -> [a] drop :: Int -> [a] -> [a] splitAt :: Int -> [a] -> ([a], [a]) subseq :: Int -> Int -> [a] -> [a] filter :: (a -> Bool) -> [a] -> [a] partition :: (a -> Bool) -> [a] -> ([a], [a]) takeWhile :: (a -> Bool) -> [a] -> [a] dropWhile :: (a -> Bool) -> [a] -> [a] splitWhile :: (a -> Bool) -> [a] -> ([a], [a]) zip :: [a] -> [b] -> [(a, b)] zip3 :: [a] -> [b] -> [c] -> [(a, b, c)] zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d] unzip :: [(a, b)] -> ([a], [b]) unzip3 :: [(a, b, c)] -> ([a], [b], [c]) unzipWith :: (a -> b) -> (a -> c) -> [a] -> ([b], [c]) unzipWith3 :: (a -> b) -> (a -> c) -> (a -> d) -> [a] -> ([b], [c], [d]) strict :: [a] -> [a] strictWith :: (a -> b) -> [a] -> [a] structuralInvariant :: [a] -> Bool moduleName :: String instance Data.Edison.Seq.Sequence [] -- | The collection abstraction includes sets, bags and priority -- queues (heaps). Collections are defined in Edison as a set of eight -- classes. -- -- All collections assume at least an equality relation of elements, and -- may also assume an ordering relation. -- -- The hierarchy contains a root class CollX together with seven -- subclasses satisfying one or more of three common sub-properties: -- -- -- -- Because collections encompass a wide range of abstractions, there is -- no single name that is suitable for all collection type constructors. -- However, most modules implementing collections will define a type -- constructor named either Bag, Set, or Heap. -- -- Notes on observability -- -- Note that the equality relation defined by the Eq class is not -- necessarily true equality. Very often it is merely an equivalence -- relation, where two equivalent values may be distinguishable by other -- means. For example, we might consider two binary trees to be equal if -- they contain the same elements, even if their shapes are different. -- -- Because of this phenomenon, implementations of observable collections -- (ie, collections where it is possible to inspect the elements) are -- rather constrained. Such an implementation must retain the actual -- elements that were inserted. For example, it is not possible in -- general to represent an observable bag as a finite map from elements -- to counts, because even if we know that a given bag contains, say, -- three elements from some equivalence class, we do not necessarily know -- which three. -- -- On the other hand, implementations of non-observable -- collections have much greater freedom to choose abstract -- representations of each equivalence class. For example, representing a -- bag as a finite map from elements to counts works fine if we never -- need to know which representatives from an equivalence class -- are actually present. As another example, consider the -- UniqueHash class defined in Data.Edison.Prelude. If we -- know that the hash function yields a unique integer for each -- equivalence class, then we can represent a collection of hashable -- elements simply as a collection of integers. With such a -- representation, we can still do many useful things like testing for -- membership; we just can't support functions like fold or -- filter that require the elements themselves, rather than the -- hashed values. module Data.Edison.Coll -- | The empty collection. Equivalant to mempty from the -- Monoid instance. -- -- This function is always unambiguous. empty :: CollX c a => c -- | Merge two collections. For sets, it is unspecified which element is -- kept in the case of duplicates. Equivalant to mappend from -- the Monoid instance. -- -- This function is ambiguous at set types if the sets are not -- disjoint. Otherwise it is unambiguous. union :: CollX c a => c -> c -> c -- | This is the root class of the collection hierarchy. However, it is -- perfectly adequate for many applications that use sets or bags. class (Eq a, Monoid c) => CollX c a | c -> a -- | create a singleton collection -- -- This function is always unambiguous. singleton :: CollX c a => a -> c -- | Convert a sequence to a collection. For sets, it is unspecified which -- element is kept in case of duplicates. -- -- This function is ambiguous at set types if more than one -- equivalent item is in the sequence. Otherwise it is -- unambiguous. fromSeq :: (CollX c a, Sequence seq) => seq a -> c -- | Merge a sequence of collections. For sets, it is unspecified which -- element is kept in the case of duplicates. -- -- This function is ambiguous at set types if the sets in the -- sequence are not mutually disjoint. Otherwise it is -- unambiguous. unionSeq :: (CollX c a, Sequence seq) => seq c -> c -- | Insert an element into a collection. For sets, if an equal element is -- already in the set, the newly inserted element is kept, and the old -- element is discarded. -- -- This function is always unambiguous. insert :: CollX c a => a -> c -> c -- | Insert a sequence of elements into a collection. For sets, the -- behavior with regard to multiple equal elements is unspecified. -- -- This function is ambiguous at set types if the sequence -- contains more than one equivalent item or an item which is already in -- the set. Otherwise it is unambiguous. insertSeq :: (CollX c a, Sequence seq) => seq a -> c -> c -- | Delete a single occurrence of the given element from a collection. For -- bags, it is unspecified which element will be deleted. -- -- This function is ambiguous at bag types if more than one item -- exists in the bag equivalent to the given item. Otherwise it is -- unambiguous. delete :: CollX c a => a -> c -> c -- | Delete all occurrences of an element from a collection. For sets this -- operation is identical to delete. -- -- This function is always unambiguous. deleteAll :: CollX c a => a -> c -> c -- | Delete a single occurrence of each of the given elements from a -- collection. For bags, there may be multiple occurrences of a given -- element in the collection, in which case it is unspecified which is -- deleted. -- -- This function is ambiguous at bag types if more than one item -- exists in the bag equivalent to any item in the list and the number of -- equivalent occurrences of that item in the sequence is less than the -- number of occurrences in the bag. Otherwise it is unambiguous. deleteSeq :: (CollX c a, Sequence seq) => seq a -> c -> c -- | Test whether the collection is empty. -- -- Axioms: -- -- -- -- This function is always unambiguous. null :: CollX c a => c -> Bool -- | Return the number of elements in the collection. -- -- This function is always unambiguous. size :: CollX c a => c -> Int -- | Test whether the given element is in the collection. -- -- Axioms: -- -- -- -- This function is always unambiguous. member :: CollX c a => a -> c -> Bool -- | Count how many copies of the given element are in the collection. For -- sets, this will always return 0 or 1. -- -- This function is always unambiguous. count :: CollX c a => a -> c -> Int -- | Semanticly, this function is a partial identity function. If the -- datastructure is infinite in size or contains exceptions or -- non-termination in the structure itself, then strict will -- result in bottom. Operationally, this function walks the datastructure -- forcing any closures. In many collections, the collction "shape" -- depends on the value of the elemnts; in such cases, the values of the -- elements will be forced to the extent necessary to force the structure -- of the collection, but no further. -- -- This function is always unambiguous. strict :: CollX c a => c -> c -- | A method to facilitate unit testing. Returns True if the -- structural invariants of the implementation hold for the given -- collection. If this function returns False, it represents a -- bug; generally, either the implementation itself is flawed, or an -- unsafe operation has been used while violating the preconditions. structuralInvariant :: CollX c a => c -> Bool -- | The name of the module implementing c instanceName :: CollX c a => c -> String -- | Collections for which the elements have an ordering relation. class (CollX c a, Ord a) => OrdCollX c a | c -> a -- | Delete the minimum element from the collection. If there is more than -- one minimum, it is unspecified which is deleted. If the collection is -- empty, it will be returned unchanged. -- -- This function is ambiguous at bag types if more than one -- minimum element exists in the bag. Otherwise it is unambiguous. deleteMin :: OrdCollX c a => c -> c -- | Delete the maximum element from the collection. If there is more than -- one maximum, it is unspecified which is deleted. If the collection is -- empty, it will be returned unchanged. -- -- This function is ambiguous at bag types if more than one -- maximum element exists in the bag. Otherwise it is unambiguous. deleteMax :: OrdCollX c a => c -> c -- | Insert an element into a collection which is guaranteed to be -- <= any existing elements in the collection. For sets, the -- precondition is strengthened to <. -- -- This function is unambiguous, under the above preconditions. unsafeInsertMin :: OrdCollX c a => a -> c -> c -- | Insert an element into a collection which is guaranteed to be -- >= any existing elements in the collection. For sets, the -- precondition is strengthened to >. -- -- This function is unambiguous, under the above preconditions. unsafeInsertMax :: OrdCollX c a => a -> c -> c -- | Convert a sequence in non-decreasing order into a collection. For -- sets, the sequence must be in increasing order. -- -- This function is unambiguous, under the above preconditions. unsafeFromOrdSeq :: (OrdCollX c a, Sequence seq) => seq a -> c -- | Union two collections where every element in the first collection is -- <= every element in the second collection. For sets, this -- precondition is strengthened to <. -- -- This function is unambiguous, under the above preconditions. unsafeAppend :: OrdCollX c a => c -> c -> c -- | Extract the sub-collection of elements < the given -- element. -- -- Axioms: -- -- -- -- This function is always unambiguous. filterLT :: OrdCollX c a => a -> c -> c -- | Extract the sub-collection of elements <= the given -- element. -- -- Axioms: -- -- -- -- This function is always unambiguous. filterLE :: OrdCollX c a => a -> c -> c -- | Extract the sub-collection of elements > the given -- element. -- -- Axioms: -- -- -- -- This function is always unambiguous. filterGT :: OrdCollX c a => a -> c -> c -- | Extract the sub-collection of elements >= the given -- element. -- -- Axioms: -- -- -- -- This function is always unambiguous. filterGE :: OrdCollX c a => a -> c -> c -- | Split a collection into those elements < a given element -- and those >=. -- -- Axioms: -- -- -- -- This function is always unambiguous. partitionLT_GE :: OrdCollX c a => a -> c -> (c, c) -- | Split a collection into those elements <= a given element -- and those >. -- -- Axioms: -- -- -- -- This function is always unambiguous. partitionLE_GT :: OrdCollX c a => a -> c -> (c, c) -- | Split a collection into those elements < a given element -- and those >. All elements equal to the given element are -- discarded. -- -- Axioms: -- -- -- -- This function is always unambiguous. partitionLT_GT :: OrdCollX c a => a -> c -> (c, c) -- | A collection where the set property is maintained; that is, a set -- contains at most one element of the equivalence class formed by the -- Eq instance on the elements. class CollX c a => SetX c a | c -> a -- | Computes the intersection of two sets. It is unspecified which element -- is kept when equal elements appear in each set. -- -- This function is ambiguous, except when the sets are disjoint. intersection :: SetX c a => c -> c -> c -- | Computes the difference of two sets; that is, all elements in the -- first set which are not in the second set. -- -- This function is always unambiguous. difference :: SetX c a => c -> c -> c -- | Computes the symmetric difference of two sets; that is, all elements -- which appear in exactily one of the two sets. -- -- This function is always unambiguous. symmetricDifference :: SetX c a => c -> c -> c -- | Test whether the first set is a proper subset of the second set; that -- is, if every element in the first set is also a member of the second -- set AND there exists some element in the second set which is not -- present in the first. -- -- This function is always unambiguous. properSubset :: SetX c a => c -> c -> Bool -- | Test whether the first set is a subset of the second set; that is, if -- every element in the first set is also a member of the second set. -- -- This function is always unambiguous. subset :: SetX c a => c -> c -> Bool -- | Sets where the elements also have an ordering relation. This class -- contains no methods; it is only an abbreviation for the context -- (OrdCollX c a,SetX c a). class (OrdCollX c a, SetX c a) => OrdSetX c a | c -> a -- | Collections with observable elements. See the module documentation for -- comments on observability. class CollX c a => Coll c a | c -> a -- | List the elements of the collection in an unspecified order. -- -- This function is ambiguous iff the collection contains more -- than one element. toSeq :: (Coll c a, Sequence seq) => c -> seq a -- | Lookup one element equal to the given element. If no elements exist in -- the collection equal to the given element, an error is signaled. If -- multiple copies of the given element exist in the collection, it is -- unspecified which is returned. -- -- This function is ambiguous at bag types, when more than one -- element equivalent to the given item is in the bag. Otherwise it is -- unambiguous. lookup :: Coll c a => a -> c -> a -- | Lookup one element equal to the given element. If no elements exist in -- the collection equal to the given element, fail is called. If -- multiple copies of the given element exist in the collection, it is -- unspecified which is returned. -- -- This function is ambiguous at bag types, when more than one -- element equivalent to the given item is in the bag. Otherwise it is -- unambiguous. lookupM :: (Coll c a, Monad m) => a -> c -> m a -- | Return a sequence containing all elements in the collection equal to -- the given element in an unspecified order. -- -- This function is ambiguous at bag types, when more than one -- element equivalent to the given item is in the bag. Otherwise it is -- unambiguous. lookupAll :: (Coll c a, Sequence seq) => a -> c -> seq a -- | Lookup one element equal to the (second) given element in the -- collection. If no elements exist in the collection equal to the given -- element, then the default element is returned. -- -- This function is ambiguous at bag types, when more than one -- element equivalent to the given item is in the bag. Otherwise it is -- unambiguous. lookupWithDefault :: Coll c a => a -> a -> c -> a -- | Fold over all the elements in a collection in an unspecified order. -- -- fold f is unambiguous iff f is -- fold-commutative. fold :: Coll c a => (a -> b -> b) -> b -> c -> b -- | A strict variant of fold. -- -- fold' f is unambiguous iff f is -- fold-commutative. fold' :: Coll c a => (a -> b -> b) -> b -> c -> b -- | Fold over all the elements in a collection in an unspecified order. An -- error is signaled if the collection is empty. -- -- fold1 f is unambiguous iff f is -- fold-commutative. fold1 :: Coll c a => (a -> a -> a) -> c -> a -- | A strict variant of fold1. -- -- fold1' f is unambiguous iff f is -- fold-commutative. fold1' :: Coll c a => (a -> a -> a) -> c -> a -- | Remove all elements not satisfying the predicate. -- -- This function is always unambiguous. filter :: Coll c a => (a -> Bool) -> c -> c -- | Returns two collections, the first containing all the elements -- satisfying the predicate, and the second containing all the elements -- not satisfying the predicate. -- -- This function is always unambiguous. partition :: Coll c a => (a -> Bool) -> c -> (c, c) -- | Similar to strict, this function walks the datastructure -- forcing closures. However, strictWith will additionally apply -- the given function to the collection elements, force the result using -- seq, and then ignore it. This function can be used to perform -- various levels of forcing on the sequence elements. In particular: -- --
--   strictWith id xs
--   
-- -- will force the spine of the datastructure and reduce each element to -- WHNF. -- -- This function is always unambiguous. strictWith :: Coll c a => (a -> b) -> c -> c -- | Collections with observable elements where the elements additionally -- have an ordering relation. See the module documentation for comments -- on observability. class (Coll c a, OrdCollX c a) => OrdColl c a | c -> a -- | Return the minimum element in the collection, together with the -- collection without that element. If there are multiple copies of the -- minimum element, it is unspecified which is chosen. Note that -- minView, minElem, and deleteMin may make -- different choices. Calls fail if the collection is empty. -- -- This function is ambiguous at bag types, if more than one -- minimum element exists in the bag. Otherwise, it is -- unambiguous. minView :: (OrdColl c a, Monad m) => c -> m (a, c) -- | Return the minimum element in the collection. If there are multiple -- copies of the minimum element, it is unspecified which is chosen. -- Note that minView, minElem, and deleteMin -- may make different choices. Signals an error if the collection is -- empty. -- -- This function is ambiguous at bag types, if more than one -- minimum element exists in the bag. Otherwise, it is -- unambiguous. minElem :: OrdColl c a => c -> a -- | Return the maximum element in the collection, together with the -- collection without that element. If there are multiple copies of the -- maximum element, it is unspecified which is chosen. Note that -- maxView, maxElem and deleteMax may make different -- choices. Calls fail if the collection is empty. -- -- This function is ambiguous at bag types, if more than one -- maximum element exists in the bag. Otherwise, it is -- unambiguous. maxView :: (OrdColl c a, Monad m) => c -> m (a, c) -- | Return the maximum element in the collection. If there are multiple -- copies of the maximum element, it is unspecified which is chosen. -- Note that maxView, maxElem and deleteMax -- may make different choices. Signals an error if the collection is -- empty. -- -- This function is ambiguous at bag types, if more than one -- maximum element exists in the bag. Otherwise, it is -- unambiguous. maxElem :: OrdColl c a => c -> a -- | Fold across the elements in non-decreasing order with right -- associativity. (For sets, this will always be increasing order) -- -- This function is unambiguous if the combining function is -- fold-commutative, at all set types, and at bag types where no two -- equivalent elements exist in the bag. Otherwise it is -- ambiguous. foldr :: OrdColl c a => (a -> b -> b) -> b -> c -> b -- | A strict variant of foldr. -- -- This function is unambiguous if the combining function is -- fold-commutative, at all set types, and at bag types where no two -- equivalent elements exist in the bag. Otherwise it is -- ambiguous. foldr' :: OrdColl c a => (a -> b -> b) -> b -> c -> b -- | Fold across the elements in non-decreasing order with left -- associativity. (For sets, this will always be increasing order) -- -- This function is unambiguous if the combining function is -- fold-commutative, at all set types, and at bag types where no two -- equivalent elements exist in the bag. Otherwise it is -- ambiguous. foldl :: OrdColl c a => (b -> a -> b) -> b -> c -> b -- | A strict variant of foldl. -- -- This function is unambiguous if the combining function is -- fold-commutative, at all set types, and at bag types where no two -- equivalent elements exist in the bag. Otherwise it is -- ambiguous. foldl' :: OrdColl c a => (b -> a -> b) -> b -> c -> b -- | Fold across the elements in non-decreasing order with right -- associativity, or signal an error if the collection is empty. (For -- sets, this will always be increasing order) -- -- This function is unambiguous if the combining function is -- fold-commutative, at all set types, and at bag types where no two -- equivalent elements exist in the bag. Otherwise it is -- ambiguous. foldr1 :: OrdColl c a => (a -> a -> a) -> c -> a -- | A strict variant of foldr1. -- -- This function is unambiguous if the combining function is -- fold-commutative, at all set types, and at bag types where no two -- equivalent elements exist in the bag. Otherwise it is -- ambiguous. foldr1' :: OrdColl c a => (a -> a -> a) -> c -> a -- | Fold across the elements in non-decreasing order with left -- associativity, or signal an error if the collection is empty. (For -- sets, this will always be increasing order) -- -- This function is unambiguous if the combining function is -- fold-commutative, at all set types, and at bag types where no two -- equivalent elements exist in the bag. Otherwise it is -- ambiguous. foldl1 :: OrdColl c a => (a -> a -> a) -> c -> a -- | A strict variant of foldl1. -- -- This function is unambiguous if the combining function is -- fold-commutative, at all set types, and at bag types where no two -- equivalent elements exist in the bag. Otherwise it is -- ambiguous. foldl1' :: OrdColl c a => (a -> a -> a) -> c -> a -- | List the elements in non-decreasing order. (For sets, this will always -- be increasing order) -- -- At set types, this function is unambiguous. At bag types, it is -- unambiguous if no two equivalent elements exist in the bag; -- otherwise it is ambiguous. toOrdSeq :: (OrdColl c a, Sequence seq) => c -> seq a -- | Map a monotonic function across all elements of a collection. The -- function is required to satisfy the following precondition: -- --
--   forall x y. x < y ==> f x < f y
--   
-- -- This function is unambiguous, under the precondition. unsafeMapMonotonic :: OrdColl c a => (a -> a) -> c -> c -- | Collections with observable elements where the set property is -- maintained; that is, a set contains at most one element of the -- equivalence class formed by the Eq instance on the elements. -- -- WARNING: Each of the following "With" functions is unsafe. The -- passed in combining functions are used to choose which element is kept -- in the case of duplicates. They are required to satisfy the -- precondition that, given two equal elements, they return a third -- element equal to the other two. Usually, the combining function just -- returns its first or second argument, but it can combine elements in -- non-trivial ways. -- -- The combining function should usually be associative. Where the -- function involves a sequence of elements, the elements will be -- combined from left-to-right, but with an unspecified associativity. -- -- For example, if x == y == z, then fromSeqWith (+) -- [x,y,z] equals either single (x + (y + z)) or single -- ((x + y) + z) class (Coll c a, SetX c a) => Set c a | c -> a -- | Same as fromSeq but with a combining function to resolve -- duplicates. -- -- This function is unambiguous under the "with" precondition if -- the combining function is associative. Otherwise it is -- ambiguous. fromSeqWith :: (Set c a, Sequence seq) => (a -> a -> a) -> seq a -> c -- | Same as insert but with a combining function to resolve -- duplicates. -- -- This function is unambiguous under the "with" precondition. insertWith :: Set c a => (a -> a -> a) -> a -> c -> c -- | Same as insertSeq but with a combining function to resolve -- duplicates. -- -- This function is unambiguous under the "with" precondition if -- the combining function is associative. Otherwise it is -- ambiguous. insertSeqWith :: (Set c a, Sequence seq) => (a -> a -> a) -> seq a -> c -> c -- | Left biased union. -- -- Axioms: -- -- -- -- This function is always unambiguous. unionl :: Set c a => c -> c -> c -- | Right biased union. -- -- Axioms: -- -- -- -- This function is always unambiguous. unionr :: Set c a => c -> c -> c -- | Same as union, but with a combining function to resolve -- duplicates. -- -- This function is unambiguous under the "with" precondition. unionWith :: Set c a => (a -> a -> a) -> c -> c -> c -- | Same as unionSeq, but with a combining function to resolve -- duplicates. -- -- This function is unambiguous under the "with" precondition if -- the combining function is associative. Otherwise it is -- ambiguous. unionSeqWith :: (Set c a, Sequence seq) => (a -> a -> a) -> seq (c) -> c -- | Same as intersection, but with a combining function to resolve -- duplicates. -- -- This function is unambiguous under the "with" precondition. intersectionWith :: Set c a => (a -> a -> a) -> c -> c -> c -- | Collections with observable elements where the set property is -- maintained and where additionally, there is an ordering relation on -- the elements. This class introduces no new methods, and is simply an -- abbreviation for the context: -- --
--   (OrdColl c a,Set c a)
--   
class (OrdColl c a, Set c a) => OrdSet c a | c -> a fromList :: CollX c a => [a] -> c insertList :: CollX c a => [a] -> c -> c unionList :: CollX c a => [c] -> c deleteList :: CollX c a => [a] -> c -> c unsafeFromOrdList :: OrdCollX c a => [a] -> c toList :: Coll c a => c -> [a] lookupList :: Coll c a => a -> c -> [a] toOrdList :: OrdColl c a => c -> [a] fromListWith :: Set c a => (a -> a -> a) -> [a] -> c insertListWith :: Set c a => (a -> a -> a) -> [a] -> c -> c unionListWith :: Set c a => (a -> a -> a) -> [c] -> c -- | This module provides implementations of several useful operations that -- are not included in the collection classes themselves. This is usually -- because the operation involves transforming a collection into a -- different type of collection; such operations cannot be typed using -- the collection classes without significantly complicating them. -- -- Be aware that these functions are defined using the external class -- interfaces and may be less efficient than corresponding, but more -- restrictively typed, functions in the collection classes. module Data.Edison.Coll.Utils -- | Apply a function across all the elements in a collection and transform -- the collection type. map :: (Coll cin a, CollX cout b) => (a -> b) -> (cin -> cout) -- | Map a partial function across all elements of a collection and -- transform the collection type. mapPartial :: (Coll cin a, CollX cout b) => (a -> Maybe b) -> (cin -> cout) -- | Map a monotonic function across all the elements of a collection and -- transform the collection type. The function is required to satisfy the -- following precondition: -- --
--   forall x y. x < y ==> f x < f y
--   
unsafeMapMonotonic :: (OrdColl cin a, OrdCollX cout b) => (a -> b) -> (cin -> cout) -- | Map a collection-producing function across all elements of a -- collection and collect the results together using union. unionMap :: (Coll cin a, CollX cout b) => (a -> cout) -> (cin -> cout) -- | The associative collection abstraction includes finite maps, -- finite relations, and priority queues where the priority is separate -- from the element. Associative collections are defined in Edison as a -- set of eight classes. -- -- Note that this hierarchy mirrors the hierarchy for collections, but -- with the addition of Functor as a superclass of every -- associative collection. See Data.Edison.Coll for a description -- of the class hierarchy. -- -- In almost all cases, associative collections make no guarantees about -- behavior with respect to the actual keys stored and (in the case of -- observable maps) which keys can be retrieved. We adopt the convention -- that methods which create associative collections are -- unambiguous with respect to the key storage behavior, but that -- methods which can observe keys are ambiguous with respect to -- the actual keys returned. -- -- In all cases where an operation is ambiguous with respect to the key, -- the operation is rendered unambiguous if the Eq -- instance on keys corresponds to indistinguisability. module Data.Edison.Assoc -- | Apply a function to the elements of every binding in the associative -- collection. Identical to fmap from Functor. -- -- This function is always unambiguous. map :: AssocX m k => (a -> b) -> m a -> m b -- | The root class of the associative collection hierarchy. class (Eq k, Functor m) => AssocX m k | m -> k -- | The empty associative collection. -- -- This function is always unambiguous. empty :: AssocX m k => m a -- | Create an associative collection with a single binding. -- -- This function is always unambiguous. singleton :: AssocX m k => k -> a -> m a -- | Create an associative collection from a list of bindings. Which -- element and key are kept in the case of duplicate keys is unspecified. -- -- This function is ambiguous at finite map types if the sequence -- contains more than one equivalent key. Otherwise it is -- unambiguous. fromSeq :: (AssocX m k, Sequence seq) => seq (k, a) -> m a -- | Add a binding to an associative collection. For finite maps, -- insert keeps the new element in the case of duplicate keys. -- -- This function is unambiguous. insert :: AssocX m k => k -> a -> m a -> m a -- | Add a sequence of bindings to a collection. For finite maps, which key -- and which element are kept in the case of duplicates is unspecified. -- However, if a key appears in the sequence and in the map, (one of) the -- elements in the list will be given preference. -- -- This function is ambiguous at finite map types if the sequence -- contains more than one equivalent key. Otherwise it is -- unambiguous. insertSeq :: (AssocX m k, Sequence seq) => seq (k, a) -> m a -> m a -- | Merge two associative collections. For finite maps, which element to -- keep in the case of duplicate keys is unspecified. -- -- This function is ambiguous at finite map types if the map keys -- are not disjoint. Otherwise it is unambiguous. union :: AssocX m k => m a -> m a -> m a -- | Merge a sequence of associative collections. Which element to keep in -- the case of duplicate keys is unspecified. -- -- This function is ambiguous at finite map types if the map keys -- are not mutually disjoint. Otherwise it is unambiguous. unionSeq :: (AssocX m k, Sequence seq) => seq (m a) -> m a -- | Delete one binding with the given key, or leave the associative -- collection unchanged if it does not contain the key. For bag-like -- associative collections, it is unspecified which binding will be -- removed. -- -- This function is ambiguous at finite relation types if the key -- appears more than once in the relation. Otherwise it is -- unambiguous. delete :: AssocX m k => k -> m a -> m a -- | Delete all bindings with the given key, or leave the associative -- collection unchanged if it does not contain the key. -- -- This function is always unambiguous. deleteAll :: AssocX m k => k -> m a -> m a -- | Delete a single occurrence of each of the given keys from an -- associative collection. For bag-like associative collections -- containing duplicate keys, it is unspecified which bindings will be -- removed. -- -- This function is ambiguous at finite relation types if any key -- appears both in the sequence and in the finite relation AND the number -- of occurrences in the sequence is less than the number of occurrences -- in the finite relation. Otherwise it is unambiguous. deleteSeq :: (AssocX m k, Sequence seq) => seq k -> m a -> m a -- | Test whether the associative collection is empty. -- -- Axioms: -- -- -- -- This function is always unambiguous. null :: AssocX m k => m a -> Bool -- | Return the number of bindings in the associative collection. -- -- This function is always unambiguous. size :: AssocX m k => m a -> Int -- | Test whether the given key is bound in the associative collection. -- -- This function is always unambiguous. member :: AssocX m k => k -> m a -> Bool -- | Returns the number of bindings with the given key. For finite maps -- this will always return 0 or 1. -- -- This function is always unambiguous. count :: AssocX m k => k -> m a -> Int -- | Find the element associated with the given key. Signals an error if -- the given key is not bound. If more than one element is bound by the -- given key, it is unspecified which is returned. -- -- This function is ambiguous at finite relation types if the key -- appears more than once in the finite relation. Otherwise, it is -- unambiguous. lookup :: AssocX m k => k -> m a -> a -- | Find the element associated with the given key. Calls fail if -- the given key is not bound. If more than one element is bound by the -- given key, it is unspecified which is returned. -- -- This function is ambiguous at finite relation types if the key -- appears more than once in the finite relation. Otherwise, it is -- unambiguous. lookupM :: (AssocX m k, Monad rm) => k -> m a -> rm a -- | Return all elements bound by the given key in an unspecified order. -- -- This function is ambiguous at finite relation types if the key -- appears more than once in the finite relation. Otherwise, it is -- unambiguous. lookupAll :: (AssocX m k, Sequence seq) => k -> m a -> seq a -- | Find the element associated with the given key; return the element and -- the collection with that element deleted. Signals an error if the -- given key is not bound. If more than one element is bound by the given -- key, it is unspecified which is deleted and returned. -- -- This function is ambiguous at finite relation types if the key -- appears more than once in the finite relation. Otherwise, it is -- unambiguous. lookupAndDelete :: AssocX m k => k -> m a -> (a, m a) -- | Find the element associated with the given key; return the element and -- the collection with that element deleted. Calls fail if the -- given key is not bound. If more than one element is bound by the given -- key, it is unspecified which is deleted and returned. -- -- This function is ambiguous at finite relation types if the key -- appears more than once in the finite relation. Otherwise, it is -- unambiguous. lookupAndDeleteM :: (AssocX m k, Monad rm) => k -> m a -> rm (a, m a) -- | Find all elements bound by the given key; return a sequence containing -- all such bound elements in an unspecified order and the collection -- with all such elements deleted. -- -- This function is ambiguous at finite relation types if the key -- appears more than once in the finite relation. Otherwise, it is -- unambiguous. lookupAndDeleteAll :: (AssocX m k, Sequence seq) => k -> m a -> (seq a, m a) -- | Return the element associated with the given key. If no such element -- is found, return the default. -- -- This function is ambiguous at finite relation types if the key -- appears more than once in the finite relation. Otherwise, it is -- unambiguous. lookupWithDefault :: AssocX m k => a -> k -> m a -> a -- | Change a single binding for the given key by applying a function to -- its element. If the key binds more than one element, it is unspecified -- which will be modified. If the key is not found in the collection, it -- is returned unchanged. -- -- This function is ambiguous at finite relation types if the key -- appears more than once in the finite relation. Otherwise, it is -- unambiguous. adjust :: AssocX m k => (a -> a) -> k -> m a -> m a -- | Change all bindings for the given key by applying a function to its -- elements. If the key is not found in the collection, it is returned -- unchanged. -- -- This function is always unambiguous. adjustAll :: AssocX m k => (a -> a) -> k -> m a -> m a -- | Searches for a matching key in the collection. If the key is found, -- the given function is called to adjust the value. If the key is not -- found, a new binding is inserted with the given element. If the given -- key is bound more than once in the collection, it is unspecified which -- element is adjusted. -- -- This function is ambiguous at finite relation types if the key -- appears more than once in the finite relation. Otherwise, it is -- unambiguous. adjustOrInsert :: AssocX m k => (a -> a) -> a -> k -> m a -> m a -- | Searches for all matching keys in the collection. If the key is found, -- the given function is applied to all its elements to adjust their -- values. If the key is not found, a new binding is inserted with the -- given element. -- -- This function is always unambiguous. adjustAllOrInsert :: AssocX m k => (a -> a) -> a -> k -> m a -> m a -- | Change or delete a single binding for the given key by applying a -- function to its element. If the function returns Nothing, -- then the binding will be deleted. If the key binds more than one -- element, it is unspecified which will be modified. If the key is not -- found in the collection, it is returned unchanged. -- -- This function is ambiguous at finite relation types if the key -- appears more than once in the finite relation. Otherwise, it is -- unambiguous. adjustOrDelete :: AssocX m k => (a -> Maybe a) -> k -> m a -> m a -- | Change or delete all bindings for the given key by applying a function -- to its elements. For any element where the function returns -- Nothing, the corresponding binding is deleted. If the key is -- not found in the collection, it is returned unchanged. -- -- This function is always unambiguous. adjustOrDeleteAll :: AssocX m k => (a -> Maybe a) -> k -> m a -> m a -- | Combine all the elements in the associative collection, given a -- combining function and an initial value. The elements are processed in -- an unspecified order. Note that fold ignores the keys. -- -- fold f is unambiguous iff f is -- fold-commutative. fold :: AssocX m k => (a -> b -> b) -> b -> m a -> b -- | A strict variant of fold. -- -- fold' f is unambiguous iff f is -- fold-commutative. fold' :: AssocX m k => (a -> b -> b) -> b -> m a -> b -- | Combine all the elements in a non-empty associative collection using -- the given combining function. Signals an error if the associative -- collection is empty. The elements are processed in an unspecified -- order. An implementation may choose to process the elements linearly -- or in a balanced fashion (like reduce1 on sequences). -- Note that fold1 ignores the keys. -- -- fold1 f is unambiguous iff f is -- fold-commutative. fold1 :: AssocX m k => (a -> a -> a) -> m a -> a -- | A strict variant of fold1. -- -- fold1' f is unambiguous iff f is -- fold-commutative. fold1' :: AssocX m k => (a -> a -> a) -> m a -> a -- | Extract all bindings whose elements satisfy the given predicate. -- -- This function is always unambiguous. filter :: AssocX m k => (a -> Bool) -> m a -> m a -- | Split an associative collection into those bindings which satisfy the -- given predicate, and those which do not. -- -- This function is always unambiguous. partition :: AssocX m k => (a -> Bool) -> m a -> (m a, m a) -- | Returns all the elements in an associative collection, in an -- unspecified order. -- -- This function is ambiguous iff the associative collection -- contains more than one element. elements :: (AssocX m k, Sequence seq) => m a -> seq a -- | Semanticly, this function is a partial identity function. If the -- datastructure is infinite in size or contains exceptions or -- non-termination in the structure itself, then strict will -- result in bottom. Operationally, this function walks the datastructure -- forcing any closures. Elements contained in the map are not -- forced. -- -- This function is always unambiguous. strict :: AssocX m k => m a -> m a -- | Similar to strict, this function walks the datastructure -- forcing closures. However, strictWith will additionally apply -- the given function to the map elements, force the result using -- seq, and then ignore it. This function can be used to perform -- various levels of forcing on the sequence elements. In particular: -- --
--   strictWith id xs
--   
-- -- will force the spine of the datastructure and reduce each element to -- WHNF. -- -- This function is always unambiguous. strictWith :: AssocX m k => (a -> b) -> m a -> m a -- | A method to facilitate unit testing. Returns True if the -- structural invariants of the implementation hold for the given -- associative collection. If this function returns False, it -- represents a bug; generally, either the implementation itself is -- flawed, or an unsafe operation has been used while violating the -- preconditions. structuralInvariant :: AssocX m k => m a -> Bool -- | Returns the name of the module implementing this associative -- collection. instanceName :: AssocX m k => m a -> String -- | An associative collection where the keys additionally have an ordering -- relation. class (AssocX m k, Ord k) => OrdAssocX m k | m -> k -- | Remove the binding with the minimum key, and return its element -- together with the remaining associative collection. Calls fail -- if the associative collection is empty. Which binding is removed if -- there is more than one minimum is unspecified. -- -- This function is ambiguous at finite relation types if the -- finite relation contains more than one minimum key. Otherwise it is -- unambiguous. minView :: (OrdAssocX m k, Monad rm) => m a -> rm (a, m a) -- | Find the binding with the minimum key and return its element. Signals -- an error if the associative collection is empty. Which element is -- chosen if there is more than one minimum is unspecified. -- -- This function is ambiguous at finite relation types if the -- finite relation contains more than one minimum key. Otherwise it is -- unambiguous. minElem :: OrdAssocX m k => m a -> a -- | Remove the binding with the minimum key and return the remaining -- associative collection, or return empty if it is already empty. -- -- This function is ambiguous at finite relation types if the -- finite relation contains more than one minimum key. Otherwise it is -- unambiguous. deleteMin :: OrdAssocX m k => m a -> m a -- | Insert a binding into an associative collection with the precondition -- that the given key is <= any existing keys already in the -- collection. For finite maps, this precondition is strengthened to -- <. -- -- This function is unambiguous under the preconditions. unsafeInsertMin :: OrdAssocX m k => k -> a -> m a -> m a -- | Remove the binding with the maximum key, and return its element -- together with the remaining associative collection. Calls fail -- if the associative collection is empty. Which binding is removed if -- there is more than one maximum is unspecified. -- -- This function is ambiguous at finite relation types if the -- finite relation contains more than one minimum key. Otherwise it is -- unambiguous. maxView :: (OrdAssocX m k, Monad rm) => m a -> rm (a, m a) -- | Find the binding with the maximum key and return its element. Signals -- an error if the associative collection is empty. Which element is -- chosen if there is more than one maximum is unspecified. -- -- This function is ambiguous at finite relation types if the -- finite relation contains more than one minimum key. Otherwise it is -- unambiguous. maxElem :: OrdAssocX m k => m a -> a -- | Remove the binding with the maximum key and return the remaining -- associative collection, or return empty if it is already empty. -- -- This function is ambiguous at finite relation types if the -- finite relation contains more than one minimum key. Otherwise it is -- unambiguous. deleteMax :: OrdAssocX m k => m a -> m a -- | Insert a binding into an associative collection with the precondition -- that the given key is >= any existing keys already in the -- collection. For finite maps, this precondition is strengthened to -- >. -- -- This function is unambiguous under the precondition. unsafeInsertMax :: OrdAssocX m k => k -> a -> m a -> m a -- | Fold across the elements of an associative collection in -- non-decreasing order by key with right associativity. For finite maps, -- the order is increasing. -- -- foldr f is unambiguous if f is -- fold-commutative, at finite map types, or at finite relation types if -- the relation contains no duplicate keys. Otherwise it is -- ambiguous. foldr :: OrdAssocX m k => (a -> b -> b) -> b -> m a -> b -- | A strict variant of foldr. -- -- foldr' f is unambiguous if f is -- fold-commutative, at finite map types, or at finite relation types if -- the relation contains no duplicate keys. Otherwise it is -- ambiguous. foldr' :: OrdAssocX m k => (a -> b -> b) -> b -> m a -> b -- | Fold across the elements of an associative collection in -- non-decreasing order by key with left associativity. For finite maps, -- the order is increasing. -- -- foldl f is unambiguous if f is -- fold-commutative, at finite map types, or at finite relation types if -- the relation contains no duplicate keys. Otherwise it is -- ambiguous. foldl :: OrdAssocX m k => (b -> a -> b) -> b -> m a -> b -- | A strict variant of foldl. -- -- foldl' f is unambiguous if f is -- fold-commutative, at finite map types, or at finite relation types if -- the relation contains no duplicate keys. Otherwise it is -- ambiguous. foldl' :: OrdAssocX m k => (b -> a -> b) -> b -> m a -> b -- | Fold across the elements of an associative collection in -- non-decreasing order by key with right associativity. Signals an error -- if the associative collection is empty. For finite maps, the order is -- increasing. -- -- foldr1 f is unambiguous if f is -- fold-commutative, at finite map types, or at finite relation types if -- the relation contains no duplicate keys. Otherwise it is -- ambiguous. foldr1 :: OrdAssocX m k => (a -> a -> a) -> m a -> a -- | A strict variant of foldr1. -- -- foldr1' f is unambiguous if f is -- fold-commutative, at finite map types, or at finite relation types if -- the relation contains no duplicate keys. Otherwise it is -- ambiguous. foldr1' :: OrdAssocX m k => (a -> a -> a) -> m a -> a -- | Fold across the elements of an associative collection in -- non-decreasing order by key with left associativity. Signals an error -- if the associative collection is empty. For finite maps, the order is -- increasing. -- -- foldl1 f is unambiguous if f is -- fold-commutative, at finite map types, or at finite relation types if -- the relation contains no duplicate keys. Otherwise it is -- ambiguous. foldl1 :: OrdAssocX m k => (a -> a -> a) -> m a -> a -- | A strict variant of foldl1. -- -- foldl1' f is unambiguous if f is -- fold-commutative, at finite map types, or at finite relation types if -- the relation contains no duplicate keys. Otherwise it is -- ambiguous. foldl1' :: OrdAssocX m k => (a -> a -> a) -> m a -> a -- | Convert a sequence of bindings into an associative collection with the -- precondition that the sequence is sorted into non-decreasing order by -- key. For finite maps, this precondition is strengthened to increasing -- order. -- -- This function is unambiguous under the precondition. unsafeFromOrdSeq :: (OrdAssocX m k, Sequence seq) => seq (k, a) -> m a -- | Merge two associative collections with the precondition that every key -- in the first associative collection is <= every key in the -- second associative collection. For finite maps, this precondition is -- strengthened to <. -- -- This function is unambiguous under the precondition. unsafeAppend :: OrdAssocX m k => m a -> m a -> m a -- | Extract all bindings whose keys are < the given key. -- -- This function is always unambiguous. filterLT :: OrdAssocX m k => k -> m a -> m a -- | Extract all bindings whose keys are <= the given key. -- -- This function is always unambiguous. filterLE :: OrdAssocX m k => k -> m a -> m a -- | Extract all bindings whose keys are > the given key. -- -- This function is always unambiguous. filterGT :: OrdAssocX m k => k -> m a -> m a -- | Extract all bindings whose keys are >= the given key. -- -- This function is always unambiguous. filterGE :: OrdAssocX m k => k -> m a -> m a -- | Split an associative collection into two sub-collections, containing -- those bindings whose keys are < the given key and those -- which are >=. -- -- This function is always unambiguous. partitionLT_GE :: OrdAssocX m k => k -> m a -> (m a, m a) -- | Split an associative collection into two sub-collections, containing -- those bindings whose keys are <= the given key and those -- which are >. -- -- This function is always unambiguous. partitionLE_GT :: OrdAssocX m k => k -> m a -> (m a, m a) -- | Split an associative collection into two sub-collections, containing -- those bindings whose keys are < the given key and those -- which are >. All bindings with keys equal to the given key -- are discarded. -- -- This function is always unambiguous. partitionLT_GT :: OrdAssocX m k => k -> m a -> (m a, m a) -- | An associative collection where the keys form a set; that is, each key -- appears in the associative collection at most once. class AssocX m k => FiniteMapX m k | m -> k -- | Same as fromSeq, but with a combining function to resolve -- duplicates. -- -- This function is always unambiguous. fromSeqWith :: (FiniteMapX m k, Sequence seq) => (a -> a -> a) -> seq (k, a) -> m a -- | Same as fromSeq, but with a combining function to resolve -- duplicates; the combining function takes the key in addition to the -- two elements. -- -- This function is always unambiguous. fromSeqWithKey :: (FiniteMapX m k, Sequence seq) => (k -> a -> a -> a) -> seq (k, a) -> m a -- | Same as insert, but with a combining function to resolve -- duplicates. -- -- This function is unambiguous. insertWith :: FiniteMapX m k => (a -> a -> a) -> k -> a -> m a -> m a -- | Same as insert, but with a combining function to resolve -- duplicates; the combining function takes the key in addition to the -- two elements. The key passed to the combining function is always the -- same as the given key. -- -- This function is unambiguous. insertWithKey :: FiniteMapX m k => (k -> a -> a -> a) -> k -> a -> m a -> m a -- | Same as insertSeq, but with a combining function to resolve -- duplicates. -- -- This function is unambiguous. insertSeqWith :: (FiniteMapX m k, Sequence seq) => (a -> a -> a) -> seq (k, a) -> m a -> m a -- | Same as insertSeq, but with a combining function to resolve -- duplicates; the combining function takes the key in addition to the -- two elements. -- -- This function is unambiguous. insertSeqWithKey :: (FiniteMapX m k, Sequence seq) => (k -> a -> a -> a) -> seq (k, a) -> m a -> m a -- | Left biased union. -- -- Axioms: -- -- -- -- This function is unambiguous. unionl :: FiniteMapX m k => m a -> m a -> m a -- | Right biased union. -- -- Axioms: -- -- -- -- This function is unambiguous. unionr :: FiniteMapX m k => m a -> m a -> m a -- | Same as union, but with a combining function to resolve -- duplicates. -- -- This function is unambiguous. unionWith :: FiniteMapX m k => (a -> a -> a) -> m a -> m a -> m a -- | Same as unionSeq, but with a combining function to resolve -- duplicates. -- -- This function is unambiguous. unionSeqWith :: (FiniteMapX m k, Sequence seq) => (a -> a -> a) -> seq (m a) -> m a -- | Compute the intersection of two finite maps. The resulting finite map -- will contain bindings where the keys are the set intersection of the -- keys in the argument finite maps. The combining function computes the -- value of the element given the bound elements from the argument finite -- maps. -- -- This function is unambiguous. intersectionWith :: FiniteMapX m k => (a -> b -> c) -> m a -> m b -> m c -- | Computes the difference of two finite maps; that is, all bindings in -- the first finite map whose keys to not appear in the second. -- -- This function is always unambiguous. difference :: FiniteMapX m k => m a -> m b -> m a -- | Test whether the set of keys in the first finite map is a proper -- subset of the set of keys of the second; that is, every key present in -- the first finite map is also a member of the second finite map AND -- there exists some key in the second finite map which is not present in -- the first. -- -- This function is always unambiguous. properSubset :: FiniteMapX m k => m a -> m b -> Bool -- | Test whether the set of keys in the first finite map is a subset of -- the set of keys of the second; that is, if every key present in the -- first finite map is also present in the second. -- -- This function is always unambiguous. subset :: FiniteMapX m k => m a -> m b -> Bool -- | Test whether the first map is a submap of the second map given a -- comparison function on elements; that is, if every key present in the -- first map is also present in the second map and the comparison -- function returns true when applied two the bound elements. -- -- This function is always unambiguous. submapBy :: FiniteMapX m k => (a -> a -> Bool) -> m a -> m a -> Bool -- | Test whether the first map is a proper submap of the second map given -- a comparison function on elements; that is, if every key present in -- the first map is also present in the second map and the comparison -- function returns true when applied two the bound elements AND there -- exiss some key in the second finite map which is not present in the -- first. -- -- This function is always unambiguous. properSubmapBy :: FiniteMapX m k => (a -> a -> Bool) -> m a -> m a -> Bool -- | Test whether the first map is the "same" map as the second map given a -- comparison function on elements; that is, if the first and second maps -- have the same set of keys and the comparison function returns true -- when applied to corresponding elements. -- -- This function is always unambiguous. sameMapBy :: FiniteMapX m k => (a -> a -> Bool) -> m a -> m a -> Bool -- | Finite maps where the keys additionally have an ordering relation. -- This class introduces no new methods. class (OrdAssocX m k, FiniteMapX m k) => OrdFiniteMapX m k | m -> k -- | Associative collections where the keys are observable. class AssocX m k => Assoc m k | m -> k -- | Extract the bindings of an associative collection into a sequence. The -- bindings are emitted in an unspecified order. -- -- This function is ambiguous with respect to the sequence order -- iff the associative collection contains more than one binding. -- Furthermore, it is ambiguous with respect to the actual key -- returned, unless the Eq instance on keys corresponds to -- indistinguisability. toSeq :: (Assoc m k, Sequence seq) => m a -> seq (k, a) -- | Extract the keys of an associative collection into a sequence. The -- keys are emitted in an unspecified order. For finite relations, keys -- which appear multiple times in the relation will appear as many times -- in the extracted sequence. -- -- This function is ambiguous with respect to the sequence order -- iff the associative collection contains more than one binding. -- Furthermore, it is ambiguous with respect to the actual key -- returned, unless the Eq instance on keys corresponds to -- indistinguisability. keys :: (Assoc m k, Sequence seq) => m a -> seq k -- | Apply a function to every element in an associative collection. The -- mapped function additionally takes the value of the key. -- -- This function is ambiguous with respect to the actual keys -- observed, unless the Eq instance on keys corresponds to -- indistinguisability. mapWithKey :: Assoc m k => (k -> a -> b) -> m a -> m b -- | Combine all the elements in the associative collection, given a -- combining function and an initial value. The elements are processed in -- an unspecified order. The combining function additionally takes the -- value of the key. -- -- foldWithKey f is unambiguous iff f is -- fold-commutative and the Eq instance on keys corresponds to -- indistinguisability. foldWithKey :: Assoc m k => (k -> a -> b -> b) -> b -> m a -> b -- | A strict variant of foldWithKey. -- -- foldWithKey' f is unambiguous iff f is -- fold-commutative and the Eq instance on keys corresponds to -- indistinguisability. foldWithKey' :: Assoc m k => (k -> a -> b -> b) -> b -> m a -> b -- | Extract all bindings from an associative collection which satisfy the -- given predicate. -- -- This function is ambiguous with respect to the actual keys -- observed, unless the Eq instance on keys corresponds to -- indistinguisability. filterWithKey :: Assoc m k => (k -> a -> Bool) -> m a -> m a -- | Split an associative collection into two sub-collections containing -- those bindings which satisfy the given predicate and those which do -- not. -- -- This function is ambiguous with respect to the actual keys -- observed, unless the Eq instance on keys corresponds to -- indistinguisability. partitionWithKey :: Assoc m k => (k -> a -> Bool) -> m a -> (m a, m a) -- | An associative collection with observable keys where the keys -- additionally have an ordering relation. class (Assoc m k, OrdAssocX m k) => OrdAssoc m k | m -> k -- | Delete the binding with the minimum key from an associative collection -- and return the key, the element and the remaining associative -- collection. Calls fail if the associative collection is empty. -- Which binding is chosen if there are multiple minimum keys is -- unspecified. -- -- This function is ambiguous at finite relation types if more -- than one minimum key exists in the relation. Furthermore, it is -- ambiguous with respect to the actual key observed unless the -- Eq instance on keys corresponds to indistinguisability. minViewWithKey :: (OrdAssoc m k, Monad rm) => m a -> rm ((k, a), m a) -- | Find the binding with the minimum key in an associative collection and -- return the key and the element. Signals an error if the associative -- collection is empty. Which binding is chosen if there are multiple -- minimum keys is unspecified. -- -- This function is ambiguous at finite relation types if more -- than one minimum key exists in the relation. Furthermore, it is -- ambiguous with respect to the actual key observed unless the -- Eq instance on keys corresponds to indistinguisability. minElemWithKey :: OrdAssoc m k => m a -> (k, a) -- | Delete the binding with the maximum key from an associative collection -- and return the key, the element and the remaining associative -- collection. Calls fail if the associative collection is empty. -- Which binding is chosen if there are multiple maximum keys is -- unspecified. -- -- This function is ambiguous at finite relation types if more -- than one maximum key exists in the relation. Furthermore, it is -- ambiguous with respect to the actual key observed unless the -- Eq instance on keys corresponds to indistinguisability. maxViewWithKey :: (OrdAssoc m k, Monad rm) => m a -> rm ((k, a), m a) -- | Find the binding with the maximum key in an associative collection and -- return the key and the element. Signals an error if the associative -- collection is empty. Which binding is chosen if there are multiple -- maximum keys is unspecified. -- -- This function is ambiguous at finite relation types if more -- than one maximum key exists in the relation. Furthermore, it is -- ambiguous with respect to the actual key observed unless the -- Eq instance on keys corresponds to indistinguisability. maxElemWithKey :: OrdAssoc m k => m a -> (k, a) -- | Fold over all bindings in an associative collection in non-decreasing -- order by key with right associativity, given a combining function and -- an initial value. For finite maps, the order is increasing. -- -- foldrWithKey f is ambiguous at finite relation types -- if the relation contains more than one equivalent key and f -- is not fold-commutative OR if the Eq instance on keys does -- not correspond to indistingusihability. foldrWithKey :: OrdAssoc m k => (k -> a -> b -> b) -> b -> m a -> b -- | A strict variant of foldrWithKey. -- -- foldrWithKey' f is ambiguous at finite relation types -- if the relation contains more than one equivalent key and f -- is not fold-commutative OR if the Eq instance on keys does -- not correspond to indistingusihability. Otherwise it is -- unambiguous. foldrWithKey' :: OrdAssoc m k => (k -> a -> b -> b) -> b -> m a -> b -- | Fold over all bindings in an associative collection in non-decreasing -- order by key with left associativity, given a combining function and -- an initial value. For finite maps, the order is increasing. -- -- foldlWithKey f is ambiguous at finite relation types -- if the relation contains more than one equivalent key and f -- is not fold-commutative OR if the Eq instance on keys does -- not correspond to indistingusihability. Otherwise it is -- unambiguous. foldlWithKey :: OrdAssoc m k => (b -> k -> a -> b) -> b -> m a -> b -- | A strict variant of foldlWithKey. -- -- foldlWithKey' f is ambiguous at finite relation types -- if the relation contains more than one equivalent key and f -- is not fold-commutative OR if the Eq instance on keys does -- not correspond to indistinguishability. Otherwise it is -- unambiguous. foldlWithKey' :: OrdAssoc m k => (b -> k -> a -> b) -> b -> m a -> b -- | Extract the bindings of an associative collection into a sequence, -- where the bindings are in non-decreasing order by key. For finite -- maps, this is increasing order. -- -- This function is ambiguous at finite relation types if the -- relation contains more than one equivalent key, or if the Eq -- instance on keys does not correspond to indistinguishability. toOrdSeq :: (OrdAssoc m k, Sequence seq) => m a -> seq (k, a) -- | Finite maps with observable keys. class (Assoc m k, FiniteMapX m k) => FiniteMap m k | m -> k -- | Same as union, but with a combining function to resolve -- duplicates. The combining function additionally takes the key. Which -- key is kept and passed into the combining function is unspecified. -- -- This function is unambiguous provided that the Eq -- instance on keys corresponds to indistinguishability. unionWithKey :: FiniteMap m k => (k -> a -> a -> a) -> m a -> m a -> m a -- | Same as unionSeq, but with a combining function to resolve -- duplicates. The combining function additionally takes the key. Which -- key is kept and passed into the combining function is unspecified. -- -- This function is unambiguous provided that the Eq -- instance on keys corresponds to indistinguishability. unionSeqWithKey :: (FiniteMap m k, Sequence seq) => (k -> a -> a -> a) -> seq (m a) -> m a -- | Same as intersectionWith, except that the combining function -- additionally takes the key value for each binding. Which key is kept -- and passed into the combining function is unspecified. -- -- This function is unambiguous provided the Eq instance -- on keys corresponds to indistinguishability. intersectionWithKey :: FiniteMap m k => (k -> a -> b -> c) -> m a -> m b -> m c -- | Finite maps with observable keys where the keys additionally have an -- ordering relation. This class introduces no new methods. class (OrdAssoc m k, FiniteMap m k) => OrdFiniteMap m k | m -> k -- | Specialization of submapBy where the comparison function is -- given by (==). submap :: (Eq a, FiniteMapX m k) => m a -> m a -> Bool -- | Specialization of properSubmapBy where the comparison function -- is given by (==). properSubmap :: (Eq a, FiniteMapX m k) => m a -> m a -> Bool -- | Specialization of sameMapBy where the comparison function is -- given by (==). sameMap :: (Eq a, FiniteMapX m k) => m a -> m a -> Bool fromList :: AssocX m k => [(k, a)] -> m a insertList :: AssocX m k => [(k, a)] -> m a -> m a unionList :: AssocX m k => [m a] -> m a deleteList :: AssocX m k => [k] -> m a -> m a lookupList :: AssocX m k => k -> m a -> [a] elementsList :: AssocX m k => m a -> [a] unsafeFromOrdList :: OrdAssocX m k => [(k, a)] -> m a fromListWith :: FiniteMapX m k => (a -> a -> a) -> [(k, a)] -> m a fromListWithKey :: FiniteMapX m k => (k -> a -> a -> a) -> [(k, a)] -> m a insertListWith :: FiniteMapX m k => (a -> a -> a) -> [(k, a)] -> m a -> m a insertListWithKey :: FiniteMapX m k => (k -> a -> a -> a) -> [(k, a)] -> m a -> m a unionListWith :: FiniteMapX m k => (a -> a -> a) -> [m a] -> m a toList :: Assoc m k => m a -> [(k, a)] keysList :: Assoc m k => m a -> [k] toOrdList :: OrdAssoc m k => m a -> [(k, a)] unionListWithKey :: FiniteMap m k => (k -> a -> a -> a) -> [m a] -> m a -- | This module introduces a number of infix symbols which are aliases for -- some of the operations in the sequence and set abstractions. For -- several, the argument orders are reversed to more closely match usual -- symbolic usage. -- -- The symbols are intended to evoke the the operations they represent. -- Unfortunately, ASCII is pretty limited, and Haskell 98 only allocates -- a few symbols to the operator lexical class. Thus, some of the -- operators are less evocative than one would like. A future version of -- Edison may introduce unicode operators, which will allow a wider range -- of operations to be represented symbolicly. -- -- Unlike most of the modules in Edison, this module is intended to be -- imported unqualified. However, the definition of (++) will -- conflict with the Prelude definition. Either this definition or the -- Prelude definition will need to be imported hiding ( (++) ). -- This definition subsumes the Prelude definition, and can be safely -- used in place of it. module Data.Edison.Sym -- | Left (front) cons on a sequence. The new element appears on the left. -- Identical to lcons. (<|) :: Sequence seq => a -> seq a -> seq a -- | Right (rear) cons on a sequence. The new element appears on the right. -- Identical to rcons with reversed arguments. (|>) :: Sequence seq => seq a -> a -> seq a -- | Append two sequences. Identical to append. Subsumes the Prelude -- definition. (++) :: Sequence seq => seq a -> seq a -> seq a -- | Lookup an element in a sequence. Identical to lookup with -- reversed arguments. (!) :: Sequence seq => seq a -> Int -> a -- | Subset test operation. Identical to subset. (|=) :: SetX set a => set -> set -> Bool -- | Set difference. Identical to difference. (\\) :: SetX set a => set -> set -> set -- | Set intersection. Identical to intersection. (/\) :: SetX set a => set -> set -> set -- | Set union. Identical to union. (\/) :: SetX set a => set -> set -> set -- | Edison is a library of purely functional data structures written by -- Chris Okasaki. It is named after Thomas Alva Edison and for the -- mnemonic value EDiSon (Efficent Data -- Structures). -- -- Edison provides several families of abstractions, each with multiple -- implementations. The main abstractions provided by Edison are: -- -- -- -- Conventions: -- -- Each data structure is implemented as a separate module. These modules -- should always be imported qualified to prevent a flood of -- name clashes, and it is recommended to rename the module using the -- as keyword to reduce the overhead of qualified names and to -- make substituting one implementation for another as painless as -- possible. -- -- Names have been chosen to match standard usage as much as possible. -- This means that operations for abstractions frequently share the same -- name (for example, empty, null, size, etc). -- It also means that in many cases names have been reused from the -- Prelude. However, the use of qualified imports will prevent -- name reuse from becoming name clashes. If for some reason you chose to -- import an Edison data structure unqualified, you will likely need to -- import the Prelude hiding the relevant names. -- -- Edison modules also frequently share type names. For example, most -- sequence type constructors are named Seq. This additionally -- aids substituting implementations by simply importing a different -- module. -- -- Argument orders are selected with the following points in mind: -- -- -- -- Type classes: -- -- Each family of abstractions is defined as a set of classes: a main -- class that every implementation of that abstraction should support and -- several auxiliary subclasses that an implementation may or may not -- support. However, not all applications require the power of type -- classes, so each method is also directly accessible from the -- implementation module. Thus you can choose to use overloading or not, -- as appropriate for your particular application. -- -- Documentation about the behavior of data structure operations is -- defined in the modules Data.Edison.Seq, Data.Edison.Coll -- and Data.Edison.Assoc. Implementations are required to respect -- the descriptions and axioms found in these modules. In some cases time -- complexity is also given. Implementations may differ from these time -- complexities; if so, the differences will be given in the -- documentation for the individual implementation module. -- -- Notes on Eq and Ord instances: -- -- Many Edison data structures require Eq or Ord -- contexts to define equivalence and total ordering on elements or keys. -- Edison makes the following assumptions about all such required -- instances: -- -- -- -- These assumptions correspond to the usual meanings assigned to these -- classes. If an Edison data structure is used with an Eq or -- Ord instance which violates these assumptions, then the -- behavior of that data structure is undefined. -- -- Notes on Read and Show instances: -- -- The usual Haskell convention for Read and Show -- instances (as championed by the Haskell "deriving" mechanism), is that -- show generates a string which is a valid Haskell expression -- built up using the data type's data constructors such that, if -- interpreted as Haskell code, the string would generate an identical -- data item. Furthermore, the derived Read instances are able -- to parse such strings, such that (read . show) === id. So, -- derived instances of Read and Show exhibit the -- following useful properties: -- -- -- -- For concrete data types, the deriving mechanism is usually quite -- sufficient. However, for abstract types the derived Read -- instance may allow users to create data which violates invariants. -- Furthermore, the strings resulting from show reference hidden -- data constructors which violates good software engineering principles -- and also cannot be compiled because the constructors are not available -- outside the defining module. -- -- Edison avoids most of these problems and still maintains the above -- useful properties by doing conversions to and from lists and inserting -- explicit calls to the list conversion operations. The corresponding -- Read instance strips the list conversion call before parsing -- the list. In this way, private data constructors are not revealed and -- show strings are still legal, compilable Haskell code. -- Furthermore, the showed strings gain a degree of independence from the -- underlying datastructure implementation. -- -- For example, calling show on an empty Banker's queue will -- result in the following string: -- --
--   Data.Edison.Seq.BankersQueue.fromList []
--   
-- -- Datatypes which are not native Edison data structures (such as -- StandardSet and StandardMap) may or may not provide Read or -- Show instances and, if they exist, they may or may not also -- provide the properties that Edison native Read and -- Show instances do. -- -- Notes on time complexities: -- -- Some Edison data structures (only the sequences currently) have -- detailed time complexity information. Unless otherwise stated, these -- are amortized time complexities, assuming persistent usage of the -- datastructure. Much of this data comes from: -- -- Martin Holters. Efficent Data Structures in a Lazy Functional -- Language. Master's Thesis. Chalmers University of Technology, -- Sweden. 2003. -- -- Notes on unsafe functions: -- -- There are a number of different notions of what constitutes an unsafe -- function. In Haskell, a function is generally called "unsafe" if it -- can subvert type safety or referential integrity, such as -- unsafePerformIO or unsafeCoerce#. In Edison, -- however, we downgrade the meaning of "unsafe" somewhat. An "unsafe" -- Edison function is one which, if misused, can violate the structural -- invariants of a data structure. Misusing an Edison "unsafe" function -- should never cause your runtime to crash or break referential -- integrity, but it may cause later uses of a data structure to behave -- in undefined ways. Almost all unsafe functions in Edison are labeled -- with the unsafe prefix. An exception to this rule is the -- With functions in the Set class, which are also unsafe -- but do not have the prefix. Unsafe functions will have explicit -- preconditions listed in their documentation. -- -- Notes on ambiguous functions: -- -- Edison also contains some functions which are labeled "ambiguous". -- These functions cannot violate the structural invariants of a data -- structure, but, under some conditions, the result of applying an -- ambiguous function is not well defined. For ambiguous functions, the -- result of applying the function may depend on otherwise unobservable -- internal state of the data structure, such as the actual shape of a -- balanced tree. For example, the AssocX class contains the -- fold function, which folds over the elements in the -- collection in an arbitrary order. If the combining function passed to -- fold is not fold-commutative (see below), then the result of -- the fold will depend on the actual order that elements are presented -- to the combining function, which is not defined. -- -- To aid programmers, each API function is labeled ambiguous or -- unambiguous in its documentation. If a function is unambiguous -- only under some circumstances, that will also be explicitly stated. -- -- An "unambiguous" operation is one where all correct implementations of -- the operation will return "indistinguishable" results. For concrete -- data types, "indistinguishable" means structural equality. An instance -- of an abstract data type is considered indistinguishable from another -- if all possible applications of unambiguous operations to both yield -- indistinguishable results. (Note: this definition is impredicative and -- rather imprecise. Should it become an issue, I will attempt to develop -- a better definition. I hope the intent is sufficiently clear). -- -- A higher-order unambiguous operation may be rendered ambiguous if -- passed a "function" which does not respect referential integrity (one -- containing unsafePerformIO for example). Only do something -- like this if you are 110% sure you know what you are doing, and even -- then think it over two or three times. -- -- How to choose a fold: -- -- Folds are an important class of operations on data structures -- in a functional language; they perform essentially the same role that -- iterators perform in imperative languages. Edison provides a dizzying -- array of folds which (hopefully) correspond to all the various ways a -- programmer might want to fold over a data structure. However, it can -- be difficult to know which fold to choose for a particular -- application. In general, you should choose a fold which provides the -- fewest guarantees necessary for correctness. The folds which -- have fewer guarantees give data structure implementers more leeway to -- provide efficient implementations. For example, if you which to fold a -- commutative, associative function, you should chose fold -- (which does not guarantee an order) over foldl or -- foldr, which specify particular orders. -- -- Also, if your function is strict in the accumulating argument, you -- should prefer the strict folds (eg, fold'); they will often -- provide better space behavior. Be aware, however, that the -- "strict" folds are not necessarily more strict than the -- "non-strict" folds; they merely give implementers the option to -- provide additional strictness if it improves performance. -- -- For associative collections, only use with WithKey folds if -- you actually need the value of the key. -- -- Painfully detailed information about ambiguous folds: -- -- All of the folds that are listed ambiguous are ambiguous because they -- do not or cannot guarantee a stable order with which the folding -- function will be applied. However, some functions are order -- insensitive, and the result will be unambiguous regardless of the fold -- order chosen. Here we formalize this property, which we call "fold -- commutativity". -- -- We say f :: a -> b -> b is fold-commutative iff -- f is unambiguous and -- --
--   forall w, z :: b; m, n :: a
--   
--      w = z ==> f m (f n w) = f n (f m z)
--   
-- -- where = means indistinguishability. -- -- This property is sufficient (but not necessary) to ensure that, for -- any collection of elements to fold over, folds over all permutations -- of those elements will generate indistinguishable results. In other -- words, an ambiguous fold applied to a fold-commutative combining -- function becomes unambiguous. -- -- Some fold combining functions take their arguments in the reverse -- order. We straightforwardly extend the notion of fold commutativity to -- such functions by reversing the arguments. More formally, we say g -- :: b -> a -> b is fold commutative iff flip g :: a -- -> b -> b is fold commutative. -- -- For folds which take both a key and an element value, we extend the -- notion of fold commutativity by considering the key and element to be -- a single, uncurried argument. More formally, we say g :: k -> a -- -> b -> b is fold commutative iff -- --
--   \(k,x) z -> g k x z :: (k,a) -> b -> b
--   
-- -- is fold commutative according to the above definition. -- -- Note that for g :: a -> a -> a, if g is -- unambiguous, commutative, and associative, then g is -- fold-commutative. -- -- Proof: -- --
--   let w = z, then
--   g m (g n w) = g m (g n z)     g is unambiguous
--               = g (g n z) m     commutative property of g
--               = g n (g z m)     associative property of g
--               = g n (g m z)     commutative property of g
--   
-- -- Qed. -- -- Thus, many common numeric combining functions, including (+) -- and (*) at integral types, are fold commutative and can be -- safely used with ambiguous folds. -- -- Be aware however, that (+) and (*) at -- floating point types are only approximately commutative and -- associative due to rounding errors; using ambiguous folds with these -- operations may result in subtle differences in the results. As always, -- be aware of the limitations and numeric properties of floating point -- representations. -- -- About this module: -- -- This module re-exports the various data structure abstraction classes, -- but not their methods. This allows you to write type signatures which -- have contexts that mention Edison type classes without having to -- import the appropriate modules qualified. The class methods -- are not exported to avoid name clashes. Obviously, to use the methods -- of these classes, you will have to import the appropriate modules. -- This module additionally re-exports the entire -- Data.Edison.Prelude module. -- -- Miscellaneous points: -- -- Some implementations export a few extra functions beyond those -- included in the relevant classes. These are typically operations that -- are particularly efficient for that implementation, but are not -- general enough to warrant inclusion in a class. -- -- Since qualified infix symbols are fairly ugly, they have been largely -- avoided. However, the Data.Edison.Sym module defines a number -- of infix operators which alias the prefix operators; this module is -- intended to be imported unqualified. -- -- Most of the operations on most of the data structures are strict. This -- is inevitable for data structures with non-trivial invariants. Even -- given that, however, many of the operations are stricter than -- necessary. In fact, operations are never deliberately made lazy unless -- the laziness is required by the algorithm, as can happen with -- amortized data structures. -- -- Note, however, that the various sequence implementations are always -- lazy in their elements. Similarly, associative collections are always -- lazy in their elements (but usually strict in their keys). -- Non-associative collections are usually strict in their elements. module Data.Edison -- | The Sequence class defines an interface for datatypes which -- implement sequences. A description for each function is given below. class (Functor s, MonadPlus s) => Sequence s -- | This is the root class of the collection hierarchy. However, it is -- perfectly adequate for many applications that use sets or bags. class (Eq a, Monoid c) => CollX c a | c -> a -- | Collections for which the elements have an ordering relation. class (CollX c a, Ord a) => OrdCollX c a | c -> a -- | A collection where the set property is maintained; that is, a set -- contains at most one element of the equivalence class formed by the -- Eq instance on the elements. class CollX c a => SetX c a | c -> a -- | Sets where the elements also have an ordering relation. This class -- contains no methods; it is only an abbreviation for the context -- (OrdCollX c a,SetX c a). class (OrdCollX c a, SetX c a) => OrdSetX c a | c -> a -- | Collections with observable elements. See the module documentation for -- comments on observability. class CollX c a => Coll c a | c -> a -- | Collections with observable elements where the elements additionally -- have an ordering relation. See the module documentation for comments -- on observability. class (Coll c a, OrdCollX c a) => OrdColl c a | c -> a -- | Collections with observable elements where the set property is -- maintained; that is, a set contains at most one element of the -- equivalence class formed by the Eq instance on the elements. -- -- WARNING: Each of the following "With" functions is unsafe. The -- passed in combining functions are used to choose which element is kept -- in the case of duplicates. They are required to satisfy the -- precondition that, given two equal elements, they return a third -- element equal to the other two. Usually, the combining function just -- returns its first or second argument, but it can combine elements in -- non-trivial ways. -- -- The combining function should usually be associative. Where the -- function involves a sequence of elements, the elements will be -- combined from left-to-right, but with an unspecified associativity. -- -- For example, if x == y == z, then fromSeqWith (+) -- [x,y,z] equals either single (x + (y + z)) or single -- ((x + y) + z) class (Coll c a, SetX c a) => Set c a | c -> a -- | Collections with observable elements where the set property is -- maintained and where additionally, there is an ordering relation on -- the elements. This class introduces no new methods, and is simply an -- abbreviation for the context: -- --
--   (OrdColl c a,Set c a)
--   
class (OrdColl c a, Set c a) => OrdSet c a | c -> a -- | The root class of the associative collection hierarchy. class (Eq k, Functor m) => AssocX m k | m -> k -- | An associative collection where the keys additionally have an ordering -- relation. class (AssocX m k, Ord k) => OrdAssocX m k | m -> k -- | An associative collection where the keys form a set; that is, each key -- appears in the associative collection at most once. class AssocX m k => FiniteMapX m k | m -> k -- | Finite maps where the keys additionally have an ordering relation. -- This class introduces no new methods. class (OrdAssocX m k, FiniteMapX m k) => OrdFiniteMapX m k | m -> k -- | Associative collections where the keys are observable. class AssocX m k => Assoc m k | m -> k -- | An associative collection with observable keys where the keys -- additionally have an ordering relation. class (Assoc m k, OrdAssocX m k) => OrdAssoc m k | m -> k -- | Finite maps with observable keys. class (Assoc m k, FiniteMapX m k) => FiniteMap m k | m -> k -- | Finite maps with observable keys where the keys additionally have an -- ordering relation. This class introduces no new methods. class (OrdAssoc m k, FiniteMap m k) => OrdFiniteMap m k | m -> k