-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | A library of efficient, 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 (Efficient 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.1


-- | 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:
--   
--   <pre>
--   forall x,y :: a. (x == y) implies (hash x == hash y)
--   </pre>
class Eq a => Hash a
hash :: Hash a => a -> Int

-- | This class represents hashable objects where the hash function is
--   <i>unique</i> (injective). There are no new methods, just a stronger
--   invariant:
--   
--   <pre>
--   forall x,y :: a. (x == y) iff (hash x == hash y)
--   </pre>
class Hash a => UniqueHash a

-- | This class represents hashable objects where the hash is reversible.
--   
--   <pre>
--   forall x :: a. unhash (hash x) == x
--   </pre>
--   
--   Note that:
--   
--   <pre>
--   hash (unhash i) == i
--   </pre>
--   
--   does not necessarily hold because <a>unhash</a> is not necessarily
--   defined for all <tt>i</tt>, only for all <tt>i</tt> 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
--   <tt>Monoid</tt> 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:
--   
--   <pre>
--   class (Functor s, MonadPlus s) =&gt; Sequence s
--   </pre>
--   
--   All sequences are also instances of <a>Functor</a>, <a>Monad</a>, and
--   <a>MonadPlus</a>. In addition, all sequences are expected to be
--   instances of <tt>Eq</tt>, <tt>Show</tt>, and <tt>Read</tt>, although
--   this is not enforced.
--   
--   We follow the naming convention that every module implementing
--   sequences defines a type constructor named <tt>Seq</tt>.
--   
--   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:
--   
--   <pre>
--   &lt;x0,x1,x2...,xn-1&gt;
--   </pre>
--   
--   Such that <tt>x0</tt> is at the left (front) of the sequence and
--   <tt>xn-1</tt> 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 <tt>fmap</tt> from <tt>Functor</tt>.
--   
--   <pre>
--   map f &lt;x0,...,xn-1&gt; = &lt;f x0,...,f xn-1&gt;
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>map f empty = empty</pre></li>
--   <li><pre>map f (lcons x xs) = lcons (f x) (map f xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
map :: Sequence s => (a -> b) -> s a -> s b

-- | Create a singleton sequence. Identical to <tt>return</tt> from
--   <tt>Monad</tt>.
--   
--   <pre>
--   singleton x = &lt;x&gt;
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>singleton x = lcons x empty = rcons x empty</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( 1 )</tt>
singleton :: Sequence s => a -> s a

-- | Apply a sequence-producing function to every element of a sequence and
--   flatten the result. <a>concatMap</a> is the bind <tt>(&gt;&gt;=)</tt>
--   operation of from <tt>Monad</tt> with the arguments in the reverse
--   order.
--   
--   <pre>
--   concatMap f xs = concat (map f xs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>concatMap f xs = concat (map f xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n + m )</tt> where <tt>n</tt> is the
--   length of the input sequence, <tt>m</tt> is the length of the output
--   sequence, and <tt>t</tt> is the running time of <tt>f</tt>
concatMap :: Sequence s => (a -> s b) -> s a -> s b

-- | The empty sequence. Identical to <tt>mzero</tt> from
--   <tt>MonadPlus</tt>.
--   
--   <pre>
--   empty = &lt;&gt;
--   </pre>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( 1 )</tt>
empty :: Sequence s => s a

-- | Append two sequence, with the first argument on the left and the
--   second argument on the right. Identical to <tt>mplus</tt> from
--   <tt>MonadPlus</tt>.
--   
--   <pre>
--   append &lt;x0,...,xn-1&gt; &lt;y0,...,ym-1&gt; = &lt;x0,...,xn-1,y0,...,ym-1&gt;
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>append xs ys = foldr lcons ys xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n1 )</tt>
append :: Sequence s => s a -> s a -> s a

-- | The <a>Sequence</a> 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
--   
--   <pre>
--   lcons x &lt;x0,...,xn-1&gt; = &lt;x,x0,...,xn-1&gt;
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>lcons x xs = append (singleton x) xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( 1 )</tt>
lcons :: Sequence s => a -> s a -> s a

-- | Add a new element to the right/rear of a sequence
--   
--   <pre>
--   rcons x &lt;x0,...,xn-1&gt; = &lt;x0,...,xn-1,x&gt;
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>rcons x xs = append xs (singleton x)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
rcons :: Sequence s => a -> s a -> s a

-- | Convert a list into a sequence
--   
--   <pre>
--   fromList [x0,...,xn-1] = &lt;x0,...,xn-1&gt;
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>fromList xs = foldr lcons empty xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
fromList :: Sequence s => [a] -> s a

-- | Create a sequence containing <tt>n</tt> copies of the given element.
--   Return <a>empty</a> if <tt>n&lt;0</tt>.
--   
--   <pre>
--   copy n x = &lt;x,...,x&gt;
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>n &gt; 0 ==&gt; copy n x = cons x (copy (n-1) x)</pre></li>
--   <li><pre>n &lt;= 0 ==&gt; copy n x = empty</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
copy :: Sequence s => Int -> a -> s a

-- | Separate a sequence into its first (leftmost) element and the
--   remaining sequence. Calls <a>fail</a> if the sequence is empty.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>lview empty = fail</pre></li>
--   <li><pre>lview (lcons x xs) = return (x,xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( 1 )</tt>
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.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>lhead empty = undefined</pre></li>
--   <li><pre>lhead (lcons x xs) = x</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( 1 )</tt>
lhead :: Sequence s => s a -> a

-- | Returns the first element of a sequence. Calls <a>fail</a> if the
--   sequence is empty.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>lheadM empty = fail</pre></li>
--   <li><pre>lheadM (lcons x xs) = return x</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( 1 )</tt>
lheadM :: (Sequence s, Monad m) => s a -> m a

-- | Delete the first element of the sequence. Signals error if sequence is
--   empty.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>ltail empty = undefined</pre></li>
--   <li><pre>ltail (lcons x xs) = xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( 1 )</tt>
ltail :: Sequence s => s a -> s a

-- | Delete the first element of the sequence. Calls <a>fail</a> if the
--   sequence is empty.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>ltailM empty = fail</pre></li>
--   <li><pre>ltailM (lcons x xs) = return xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( 1 )</tt>
ltailM :: (Sequence s, Monad m) => s a -> m (s a)

-- | Separate a sequence into its last (rightmost) element and the
--   remaining sequence. Calls <a>fail</a> if the sequence is empty.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>rview empty = fail</pre></li>
--   <li><pre>rview (rcons x xs) = return (x,xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
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.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>rhead empty = undefined</pre></li>
--   <li><pre>rhead (rcons x xs) = x</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
rhead :: Sequence s => s a -> a

-- | Returns the last element of the sequence. Calls <a>fail</a> if the
--   sequence is empty.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>rheadM empty = fail</pre></li>
--   <li><pre>rheadM (rcons x xs) = return x</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
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.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>rtail empty = undefined</pre></li>
--   <li><pre>rtail (rcons x xs) = xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
rtail :: Sequence s => s a -> s a

-- | Delete the last (rightmost) element of the sequence. Calls <a>fail</a>
--   of the sequence is empty
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>rtailM empty = fail</pre></li>
--   <li><pre>rtailM (rcons x xs) = return xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
rtailM :: (Sequence s, Monad m) => s a -> m (s a)

-- | Returns <a>True</a> if the sequence is empty and <a>False</a>
--   otherwise.
--   
--   <pre>
--   null &lt;x0,...,xn-1&gt; = (n==0)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>null xs = (size xs == 0)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( 1 )</tt>
null :: Sequence s => s a -> Bool

-- | Returns the length of a sequence.
--   
--   <pre>
--   size &lt;x0,...,xn-1&gt; = n
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>size empty = 0</pre></li>
--   <li><pre>size (lcons x xs) = 1 + size xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
size :: Sequence s => s a -> Int

-- | Convert a sequence to a list.
--   
--   <pre>
--   toList &lt;x0,...,xn-1&gt; = [x0,...,xn-1]
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>toList empty = []</pre></li>
--   <li><pre>toList (lcons x xs) = x : toList xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
toList :: Sequence s => s a -> [a]

-- | Flatten a sequence of sequences into a simple sequence.
--   
--   <pre>
--   concat xss = foldr append empty xss
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>concat xss = foldr append empty xss</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n + m )</tt> where <tt>n</tt> is the
--   length of the input sequence and <tt>m</tt> is length of the output
--   sequence.
concat :: Sequence s => s (s a) -> s a

-- | Reverse the order of a sequence
--   
--   <pre>
--   reverse &lt;x0,...,xn-1&gt; = &lt;xn-1,...,x0&gt;
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>reverse empty = empty</pre></li>
--   <li><pre>reverse (lcons x xs) = rcons x (reverse xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
reverse :: Sequence s => s a -> s a

-- | Reverse a sequence onto the front of another sequence.
--   
--   <pre>
--   reverseOnto &lt;x0,...,xn-1&gt; &lt;y0,...,ym-1&gt; = &lt;xn-1,...,x0,y0,...,ym-1&gt;
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>reverseOnto xs ys = append (reverse xs) ys</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n1 )</tt>
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.
--   <tt>fold</tt> is one of the few ambiguous sequence functions.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>fold f c empty = c</pre></li>
--   <li><pre>f is fold-commutative ==&gt; fold f = foldr f = foldl
--   f</pre></li>
--   </ul>
--   
--   <tt>fold f</tt> is <i>unambiguous</i> iff <tt>f</tt> is
--   fold-commutative.
--   
--   Default running type: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running tome of <tt>f</tt>.
fold :: Sequence s => (a -> b -> b) -> b -> s a -> b

-- | A strict variant of <a>fold</a>. <tt>fold'</tt> is one of the few
--   ambiguous sequence functions.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>forall a. f a _|_ = _|_ ==&gt; fold f x xs = fold' f x
--   xs</pre></li>
--   </ul>
--   
--   <tt>fold f</tt> is <i>unambiguous</i> iff <tt>f</tt> is
--   fold-commutative.
--   
--   Default running type: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running tome of <tt>f</tt>.
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.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>f is fold-commutative ==&gt; fold1 f = foldr1 f = foldl1
--   f</pre></li>
--   </ul>
--   
--   <tt>fold1 f</tt> is <i>unambiguous</i> iff <tt>f</tt> is
--   fold-commutative.
--   
--   Default running type: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running tome of <tt>f</tt>.
fold1 :: Sequence s => (a -> a -> a) -> s a -> a

-- | A strict variant of <a>fold1</a>.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>forall a. f a _|_ = _|_ ==&gt; fold1' f xs = fold1 f
--   xs</pre></li>
--   </ul>
--   
--   <tt>fold1' f</tt> is <i>unambiguous</i> iff <tt>f</tt> is
--   fold-commutative.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
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.
--   
--   <pre>
--   foldr (%) c &lt;x0,...,xn-1&gt; = x0 % (x1 % ( ... % (xn-1 % c)))
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>foldr f c empty = c</pre></li>
--   <li><pre>foldr f c (lcons x xs) = f x (foldr f c xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
foldr :: Sequence s => (a -> b -> b) -> b -> s a -> b

-- | Strict variant of <a>foldr</a>.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>forall a. f a _|_ = _|_ ==&gt; foldr f x xs = foldr' f x
--   xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
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.
--   
--   <pre>
--   foldl (%) c &lt;x0,...,xn-1&gt; = (((c % x0) % x1) % ... ) % xn-1
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>foldl f c empty = c</pre></li>
--   <li><pre>foldl f c (lcons x xs) = foldl f (f c x) xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
foldl :: Sequence s => (b -> a -> b) -> b -> s a -> b

-- | Strict variant of <a>foldl</a>.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li>forall a. f _|_ a = _|_ ==&gt; foldl f z xs = foldl' f z xs</li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
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.
--   
--   <pre>
--   foldr1 (+) &lt;x0,...,xn-1&gt;
--     | n==0 = error "ModuleName.foldr1: empty sequence"
--     | n&gt;0  = x0 + (x1 + ... + xn-1)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>foldr1 f empty = undefined</pre></li>
--   <li><pre>foldr1 f (rcons x xs) = foldr f x xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
foldr1 :: Sequence s => (a -> a -> a) -> s a -> a

-- | Strict variant of <a>foldr1</a>.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li>forall a. f a _|_ = _|_ ==&gt; foldr1 f xs = foldr1' f xs</li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
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.
--   
--   <pre>
--   foldl1 (+) &lt;x0,...,xn-1&gt;
--    | n==0 = error "ModuleName.foldl1: empty sequence"
--    | n&gt;0  = (x0 + x1) + ... + xn-1
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>foldl1 f empty = undefined</pre></li>
--   <li><pre>foldl1 f (lcons x xs) = foldl f x xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
foldl1 :: Sequence s => (a -> a -> a) -> s a -> a

-- | Strict variant of <a>foldl1</a>.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li>forall a. f _|_ a = _|_ ==&gt; foldl1 f xs = foldl1' f xs</li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
foldl1' :: Sequence s => (a -> a -> a) -> s a -> a

-- | See <a>reduce1</a> for additional notes.
--   
--   <pre>
--   reducer f x xs = reduce1 f (cons x xs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><tt>reducer f c xs = foldr f c xs</tt> for associative
--   <tt>f</tt></li>
--   </ul>
--   
--   <tt>reducer f</tt> is unambiguous iff <tt>f</tt> is an associative
--   function.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
reducer :: Sequence s => (a -> a -> a) -> a -> s a -> a

-- | Strict variant of <a>reducer</a>.
--   
--   See <a>reduce1</a> for additional notes.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>forall a. f a _|_ = _|_ &amp;&amp; forall a. f _|_ a = _|_
--   ==&gt; reducer f x xs = reducer' f x xs</pre></li>
--   </ul>
--   
--   <tt>reducer' f</tt> is unambiguous iff <tt>f</tt> is an associative
--   function.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
reducer' :: Sequence s => (a -> a -> a) -> a -> s a -> a

-- | See <a>reduce1</a> for additional notes.
--   
--   <pre>
--   reducel f x xs = reduce1 f (rcons x xs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><tt>reducel f c xs = foldl f c xs</tt> for associative
--   <tt>f</tt></li>
--   </ul>
--   
--   <tt>reducel f</tt> is unambiguous iff <tt>f</tt> is an associative
--   function.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
reducel :: Sequence s => (a -> a -> a) -> a -> s a -> a

-- | Strict variant of <a>reducel</a>.
--   
--   See <a>reduce1</a> for additional notes.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>forall a. f a _|_ = _|_ &amp;&amp; forall a. f _|_ a = _|_
--   ==&gt; reducel f x xs = reducel' f x xs</pre></li>
--   </ul>
--   
--   <tt>reducel' f</tt> is unambiguous iff <tt>f</tt> is an associative
--   function.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
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 <tt>reduce1 (%)
--   &lt;x0,x1,...,xn-1&gt;</tt> equals some complete parenthesization of
--   <tt>x0 % x1 % ... % xn-1</tt> such that the nesting depth of
--   parentheses is <tt>O( log n )</tt>. The precise shape of this
--   parenthesization is unspecified.
--   
--   <pre>
--   reduce1 f &lt;x&gt; = x
--   reduce1 f &lt;x0,...,xn-1&gt; =
--       f (reduce1 f &lt;x0,...,xi&gt;) (reduce1 f &lt;xi+1,...,xn-1&gt;)
--   </pre>
--   
--   for some <tt>i</tt> such that <tt> 0 &lt;= i &amp;&amp; i &lt; n-1
--   </tt>
--   
--   Although the exact value of i is unspecified it tends toward
--   <tt>n/2</tt> so that the depth of calls to <tt>f</tt> is at most
--   logarithmic.
--   
--   Note that <tt>reduce</tt>* 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:
--   
--   <pre>
--   mergesort xs = reducer merge empty (map singleton xs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>reduce1 f empty = undefined</pre></li>
--   <li><tt>reduce1 f xs = foldr1 f xs = foldl1 f xs</tt> for associative
--   <tt>f</tt></li>
--   </ul>
--   
--   <tt>reduce1 f</tt> is unambiguous iff <tt>f</tt> is an associative
--   function.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
reduce1 :: Sequence s => (a -> a -> a) -> s a -> a

-- | Strict variant of <a>reduce1</a>.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>forall a. f a _|_ = _|_ &amp;&amp; forall a. f _|_ a = _|_
--   ==&gt; reduce1 f xs = reduce1' f xs</pre></li>
--   </ul>
--   
--   <tt>reduce1' f</tt> is unambiguous iff <tt>f</tt> is an associative
--   function.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
reduce1' :: Sequence s => (a -> a -> a) -> s a -> a

-- | Extract a prefix of length <tt>i</tt> from the sequence. Return
--   <a>empty</a> if <tt>i</tt> is negative, or the entire sequence if
--   <tt>i</tt> is too large.
--   
--   <pre>
--   take i xs = fst (splitAt i xs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>i &lt; 0 ==&gt; take i xs = empty</pre></li>
--   <li><pre>i &gt; size xs ==&gt; take i xs = xs</pre></li>
--   <li><pre>size xs == i ==&gt; take i (append xs ys) = xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( i )</tt>
take :: Sequence s => Int -> s a -> s a

-- | Delete a prefix of length <tt>i</tt> from a sequence. Return the
--   entire sequence if <tt>i</tt> is negative, or <a>empty</a> if
--   <tt>i</tt> is too large.
--   
--   <pre>
--   drop i xs = snd (splitAt i xs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>i &lt; 0 ==&gt; drop i xs = xs</pre></li>
--   <li><pre>i &gt; size xs ==&gt; drop i xs = empty</pre></li>
--   <li><pre>size xs == i ==&gt; drop i (append xs ys) = ys</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( i )</tt>
drop :: Sequence s => Int -> s a -> s a

-- | Split a sequence into a prefix of length <tt>i</tt> and the remaining
--   sequence. Behaves the same as the corresponding calls to <a>take</a>
--   and <a>drop</a> if <tt>i</tt> is negative or too large.
--   
--   <pre>
--   splitAt i xs
--    | i &lt; 0  = (&lt;&gt;           , &lt;x0,...,xn-1&gt;)
--    | i &lt; n  = (&lt;x0,...,xi-1&gt;, &lt;xi,...,xn-1&gt;)
--    | i &gt;= n = (&lt;x0,...,xn-1&gt;, &lt;&gt;           )
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>splitAt i xs = (take i xs,drop i xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( i )</tt>
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 <a>take</a> and <a>drop</a> if
--   the start index or length are negative or too large.
--   
--   <pre>
--   subseq i len xs = take len (drop i xs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>subseq i len xs = take len (drop i xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( i + len )</tt>
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.
--   
--   <pre>
--   filter p xs = foldr pcons empty xs
--        where pcons x xs = if p x then cons x xs else xs
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>filter p empty = empty</pre></li>
--   <li><pre>filter p (lcons x xs) = if p x then lcons x (filter p xs)
--   else filter p xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>p</tt>
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.
--   
--   <pre>
--   partition p xs = (filter p xs, filter (not . p) xs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>partition p xs = (filter p xs, filter (not . p)
--   xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>p</tt>
partition :: Sequence s => (a -> Bool) -> s a -> (s a, s a)

-- | Extract the maximal prefix of elements satisfying the given predicate.
--   
--   <pre>
--   takeWhile p xs = fst (splitWhile p xs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>takeWhile p empty = empty</pre></li>
--   <li><pre>takeWhile p (lcons x xs) = if p x then lcons x (takeWhile p
--   xs) else empty</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>p</tt>
takeWhile :: Sequence s => (a -> Bool) -> s a -> s a

-- | Delete the maximal prefix of elements satisfying the given predicate.
--   
--   <pre>
--   dropWhile p xs = snd (splitWhile p xs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>dropWhile p empty = empty</pre></li>
--   <li><pre>dropWhile p (lcons x xs) = if p x then dropWhile p xs else
--   lcons x xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>p</tt>
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.
--   
--   <pre>
--   splitWhile p &lt;x0,...,xn-1&gt; = (&lt;x0,...,xi-1&gt;, &lt;xi,...,xn-1&gt;)
--     where i = min j such that p xj (or n if no such j)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>splitWhile p xs = (takeWhile p xs,dropWhile p xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>p</tt>
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.
--   
--   <pre>
--   inBounds i &lt;x0,...,xn-1&gt; = (0 &lt;= i &amp;&amp; i &lt; n)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>inBounds i xs = (0 &lt;= i &amp;&amp; i &lt; size
--   xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( i )</tt>
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.
--   
--   <pre>
--   lookup i xs@&lt;x0,...,xn-1&gt;
--     | inBounds i xs = xi
--     | otherwise = error "ModuleName.lookup: index out of bounds"
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>not (inBounds i xs) ==&gt; lookup i xs = undefined</pre></li>
--   <li><pre>size xs == i ==&gt; lookup i (append xs (lcons x ys)) =
--   x</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( i )</tt>
lookup :: Sequence s => Int -> s a -> a

-- | Return the element at the given index. All indexes are 0 based. Calls
--   <a>fail</a> if the index is out of bounds.
--   
--   <pre>
--   lookupM i xs@&lt;x0,...,xn-1&gt;
--     | inBounds i xs = Just xi
--     | otherwise = Nothing
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>not (inBounds i xs) ==&gt; lookupM i xs = fail</pre></li>
--   <li><pre>size xs == i ==&gt; lookupM i (append xs (lcons x ys)) =
--   return x</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( i )</tt>
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.
--   
--   <pre>
--   lookupWithDefault d i xs@&lt;x0,...,xn-1&gt;
--     | inBounds i xs = xi
--     | otherwise = d
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>not (inBounds i xs) ==&gt; lookupWithDefault d i xs =
--   d</pre></li>
--   <li><pre>size xs == i ==&gt; lookupWithDefault d i (append xs (lcons x
--   ys)) = x</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( i )</tt>
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.
--   
--   <pre>
--   update i y xs@&lt;x0,...,xn-1&gt;
--     | inBounds i xs = &lt;x0,...xi-1,y,xi+1,...,xn-1&gt;
--     | otherwise = xs
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>not (inBounds i xs) ==&gt; update i y xs = xs</pre></li>
--   <li><pre>size xs == i ==&gt; update i y (append xs (lcons x ys)) =
--   append xs (lcons y ys)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( i )</tt>
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.
--   
--   <pre>
--   adjust f i xs@&lt;x0,...,xn-1&gt;
--     | inBounds i xs = &lt;x0,...xi-1,f xi,xi+1,...,xn-1&gt;
--     | otherwise = xs
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>not (inBounds i xs) ==&gt; adjust f i xs = xs</pre></li>
--   <li><pre>size xs == i ==&gt; adjust f i (append xs (lcons x ys)) =
--   append xs (cons (f x) ys)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( i + t )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
adjust :: Sequence s => (a -> a) -> Int -> s a -> s a

-- | Like <a>map</a>, but include the index with each element. All indexes
--   are 0 based.
--   
--   <pre>
--   mapWithIndex f &lt;x0,...,xn-1&gt; = &lt;f 0 x0,...,f (n-1) xn-1&gt;
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>mapWithIndex f empty = empty</pre></li>
--   <li><pre>mapWithIndex f (rcons x xs) = rcons (f (size xs) x)
--   (mapWithIndex f xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
mapWithIndex :: Sequence s => (Int -> a -> b) -> s a -> s b

-- | Like <a>foldr</a>, but include the index with each element. All
--   indexes are 0 based.
--   
--   <pre>
--   foldrWithIndex f c &lt;x0,...,xn-1&gt; = 
--       f 0 x0 (f 1 x1 (... (f (n-1) xn-1 c)))
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>foldrWithIndex f c empty = c</pre></li>
--   <li><pre>foldrWithIndex f c (rcons x xs) = foldrWithIndex f (f (size
--   xs) x c) xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
foldrWithIndex :: Sequence s => (Int -> a -> b -> b) -> b -> s a -> b

-- | Strict variant of <a>foldrWithIndex</a>.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>forall i a. f i a _|_ = _|_ ==&gt; foldrWithIndex f x xs =
--   foldrWithIndex' f x xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
foldrWithIndex' :: Sequence s => (Int -> a -> b -> b) -> b -> s a -> b

-- | Like <a>foldl</a>, but include the index with each element. All
--   indexes are 0 based.
--   
--   <pre>
--   foldlWithIndex f c &lt;x0,...,xn-1&gt; =
--       f (...(f (f c 0 x0) 1 x1)...) (n-1) xn-1)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>foldlWithIndex f c empty = c</pre></li>
--   <li><pre>foldlWithIndex f c (rcons x xs) = f (foldlWithIndex f c xs)
--   (size xs) x</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
foldlWithIndex :: Sequence s => (b -> Int -> a -> b) -> b -> s a -> b

-- | Strict variant of <a>foldlWithIndex</a>.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>forall i a. f _|_ i a = _|_ ==&gt; foldlWithIndex f x xs =
--   foldlWithIndex' f x xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   running time of <tt>f</tt>
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.
--   
--   <pre>
--   zip &lt;x0,...,xn-1&gt; &lt;y0,...,ym-1&gt; = &lt;(x0,y0),...,(xj-1,yj-1)&gt;
--       where j = min {n,m}
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>zip xs ys = zipWith (,) xs ys</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( min( n1, n2 ) )</tt>
zip :: Sequence s => s a -> s b -> s (a, b)

-- | Like <a>zip</a>, but combines three sequences into triples.
--   
--   <pre>
--   zip3 &lt;x0,...,xn-1&gt; &lt;y0,...,ym-1&gt; &lt;z0,...,zk-1&gt; = 
--        &lt;(x0,y0,z0),...,(xj-1,yj-1,zj-1)&gt;
--      where j = min {n,m,k}
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>zip3 xs ys zs = zipWith3 (,,) xs ys zs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( min( n1, n2, n3 ) )</tt>
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.
--   
--   <pre>
--   zipWith f xs ys = map (uncurry f) (zip xs ys)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>zipWith f (lcons x xs) (lcons y ys) = lcons (f x y) (zipWith
--   f xs ys)</pre></li>
--   <li><pre>(null xs || null ys) ==&gt; zipWith xs ys = empty</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * min( n1, n2 ) )</tt> where <tt>t</tt>
--   is the running time of <tt>f</tt>
zipWith :: Sequence s => (a -> b -> c) -> s a -> s b -> s c

-- | Like <a>zipWith</a> but for a three-place function and three
--   sequences.
--   
--   <pre>
--   zipWith3 f xs ys zs = map (uncurry f) (zip3 xs ys zs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>zipWith3 (lcons x xs) (lcons y ys) (lcons z zs) = lcons (f x
--   y z) (zipWith3 f xs ys zs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * min( n1, n2, n3 ) )</tt> where
--   <tt>t</tt> is the running time of <tt>f</tt>
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.
--   
--   <pre>
--   unzip xs = (map fst xs, map snd xs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>unzip xys = unzipWith fst snd xys</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
unzip :: Sequence s => s (a, b) -> (s a, s b)

-- | Transpose a sequence of triples into a triple of sequences
--   
--   <pre>
--   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
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>unzip3 xyzs = unzipWith3 fst3 snd3 thd3 xyzs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
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
--   
--   <pre>
--   unzipWith f g xs = (map f xs, map g xs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>unzipWith f g xs = (map f xs, map g xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   maximum running time of <tt>f</tt> and <tt>g</tt>
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.
--   
--   <pre>
--   unzipWith3 f g h xs = (map f xs, map g xs, map h xs)
--   </pre>
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>unzipWith3 f g h xs = (map f xs,map g xs,map h xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( t * n )</tt> where <tt>t</tt> is the
--   maximum running time of <tt>f</tt>, <tt>g</tt>, and <tt>h</tt>
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 <tt>strict</tt> will
--   result in bottom. Operationally, this function walks the datastructure
--   forcing any closures. Elements contained in the sequence are
--   <i>not</i> forced.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><tt>strict xs = xs</tt> OR <tt>strict xs = _|_</tt></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   Default running time: <tt>O( n )</tt>
strict :: Sequence s => s a -> s a

-- | Similar to <a>strict</a>, this function walks the datastructure
--   forcing closures. However, <tt>strictWith</tt> will additionally apply
--   the given function to the sequence elements, force the result using
--   <tt>seq</tt>, and then ignore it. This function can be used to perform
--   various levels of forcing on the sequence elements. In particular:
--   
--   <pre>
--   strictWith id xs
--   </pre>
--   
--   will force the spine of the datastructure and reduce each element to
--   WHNF.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li>forall <tt>f :: a -&gt; b</tt>, <tt>strictWith f xs = xs</tt> OR
--   <tt>strictWith f xs = _|_</tt></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
--   
--   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 <a>True</a> if the
--   structural invariants of the implementation hold for the given
--   sequence. If this function returns <a>False</a>, 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 <a>Data.Edison.Seq</a>, except for the
--   following two trivial operations:
--   
--   <ul>
--   <li>toList, fromList <tt>O( 1 )</tt></li>
--   </ul>
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' :: (t -> t -> t) -> [t] -> t
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' :: (Num t2, Enum t2) => (t2 -> t1 -> t -> t) -> t -> [t1] -> t
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 <i>collection</i> 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 <a>CollX</a> together with seven
--   subclasses satisfying one or more of three common sub-properties:
--   
--   <ul>
--   <li><i>Uniqueness</i> Each element in the collection is unique (no two
--   elements in the collection are equal). These subclasses, indicated by
--   the name <tt>Set</tt>, represent sets rather than bags
--   (multi-sets).</li>
--   <li><i>Ordering</i> The elements have a total ordering and it is
--   possible to process the elements in non-decreasing order. These
--   subclasses, indicates by the <tt>Ord</tt> prefix, typically represent
--   either priority queues (heaps) or sets/bags implemented as binary
--   search trees.</li>
--   <li><i>Observability</i> An observable collection is one in which it
--   is possible to view the elements in a collection. The <tt>X</tt>
--   suffix indicates a lack of observability. This property is discussed
--   is greater detail below.</li>
--   </ul>
--   
--   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 <tt>Bag</tt>, <tt>Set</tt>, or <tt>Heap</tt>.
--   
--   <i>Notes on observability</i>
--   
--   Note that the equality relation defined by the <a>Eq</a> 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
--   <i>which</i> three.
--   
--   On the other hand, implementations of <i>non-observable</i>
--   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 <i>which</i> representatives from an equivalence class
--   are actually present. As another example, consider the
--   <a>UniqueHash</a> class defined in <a>Data.Edison.Prelude</a>. If we
--   know that the <a>hash</a> 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 <a>fold</a> or
--   <a>filter</a> that require the elements themselves, rather than the
--   hashed values.
module Data.Edison.Coll

-- | The empty collection. Equivalant to <tt>mempty</tt> from the
--   <tt>Monoid</tt> instance.
--   
--   This function is always <i>unambiguous</i>.
empty :: CollX c a => c

-- | Merge two collections. For sets, it is unspecified which element is
--   kept in the case of duplicates. Equivalant to <tt>mappend</tt> from
--   the <tt>Monoid</tt> instance.
--   
--   This function is <i>ambiguous</i> at set types if the sets are not
--   disjoint. Otherwise it is <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>ambiguous</i> at set types if more than one
--   equivalent item is in the sequence. Otherwise it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at set types if the sets in the
--   sequence are not mutually disjoint. Otherwise it is
--   <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>ambiguous</i> at set types if the sequence
--   contains more than one equivalent item or an item which is already in
--   the set. Otherwise it is <i>unambiguous</i>.
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 <i>ambiguous</i> at bag types if more than one item
--   exists in the bag equivalent to the given item. Otherwise it is
--   <i>unambiguous</i>.
delete :: CollX c a => a -> c -> c

-- | Delete all occurrences of an element from a collection. For sets this
--   operation is identical to <a>delete</a>.
--   
--   This function is always <i>unambiguous</i>.
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 <i>ambiguous</i> 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 <i>unambiguous</i>.
deleteSeq :: (CollX c a, Sequence seq) => seq a -> c -> c

-- | Test whether the collection is empty.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>null xs = (size xs == 0)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
null :: CollX c a => c -> Bool

-- | Return the number of elements in the collection.
--   
--   This function is always <i>unambiguous</i>.
size :: CollX c a => c -> Int

-- | Test whether the given element is in the collection.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>member x xs = (count x xs &gt; 0)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <tt>strict</tt> 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 <i>unambiguous</i>.
strict :: CollX c a => c -> c

-- | A method to facilitate unit testing. Returns <a>True</a> if the
--   structural invariants of the implementation hold for the given
--   collection. If this function returns <a>False</a>, 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 <tt>c</tt>
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 <i>ambiguous</i> at bag types if more than one
--   minimum element exists in the bag. Otherwise it is <i>unambiguous</i>.
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 <i>ambiguous</i> at bag types if more than one
--   maximum element exists in the bag. Otherwise it is <i>unambiguous</i>.
deleteMax :: OrdCollX c a => c -> c

-- | Insert an element into a collection which is guaranteed to be
--   <tt>&lt;=</tt> any existing elements in the collection. For sets, the
--   precondition is strengthened to <tt>&lt;</tt>.
--   
--   This function is <i>unambiguous</i>, under the above preconditions.
unsafeInsertMin :: OrdCollX c a => a -> c -> c

-- | Insert an element into a collection which is guaranteed to be
--   <tt>&gt;=</tt> any existing elements in the collection. For sets, the
--   precondition is strengthened to <tt>&gt;</tt>.
--   
--   This function is <i>unambiguous</i>, 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 <i>unambiguous</i>, under the above preconditions.
unsafeFromOrdSeq :: (OrdCollX c a, Sequence seq) => seq a -> c

-- | Union two collections where every element in the first collection is
--   <tt>&lt;=</tt> every element in the second collection. For sets, this
--   precondition is strengthened to <tt>&lt;</tt>.
--   
--   This function is <i>unambiguous</i>, under the above preconditions.
unsafeAppend :: OrdCollX c a => c -> c -> c

-- | Extract the sub-collection of elements <tt>&lt;</tt> the given
--   element.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>filterLT x xs = filter (&lt; x) xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
filterLT :: OrdCollX c a => a -> c -> c

-- | Extract the sub-collection of elements <tt>&lt;=</tt> the given
--   element.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>filterLE x xs = filter (&lt;= x) xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
filterLE :: OrdCollX c a => a -> c -> c

-- | Extract the sub-collection of elements <tt>&gt;</tt> the given
--   element.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>filterGT x xs = filter (&gt; x) xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
filterGT :: OrdCollX c a => a -> c -> c

-- | Extract the sub-collection of elements <tt>&gt;=</tt> the given
--   element.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>filterGE x xs = filter (&gt;= x) xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
filterGE :: OrdCollX c a => a -> c -> c

-- | Split a collection into those elements <tt>&lt;</tt> a given element
--   and those <tt>&gt;=</tt>.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>partitionLT_GE xs = partition (&lt;) xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
partitionLT_GE :: OrdCollX c a => a -> c -> (c, c)

-- | Split a collection into those elements <tt>&lt;=</tt> a given element
--   and those <tt>&gt;</tt>.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>partitionLE_GT xs = partition (&lt;=) xs</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
partitionLE_GT :: OrdCollX c a => a -> c -> (c, c)

-- | Split a collection into those elements <tt>&lt;</tt> a given element
--   and those <tt>&gt;</tt>. All elements equal to the given element are
--   discarded.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>partitionLT_GT x xs = (filterLT x xs,filterGT x
--   xs)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
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
--   <a>Eq</a> 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 <i>ambiguous</i>, 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 <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>unambiguous</i>.
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
--   <tt>(OrdCollX c a,SetX c a)</tt>.
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 <i>ambiguous</i> 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 <i>ambiguous</i> at bag types, when more than one
--   element equivalent to the given item is in the bag. Otherwise it is
--   <i>unambiguous</i>.
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, <a>fail</a> is called. If
--   multiple copies of the given element exist in the collection, it is
--   unspecified which is returned.
--   
--   This function is <i>ambiguous</i> at bag types, when more than one
--   element equivalent to the given item is in the bag. Otherwise it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at bag types, when more than one
--   element equivalent to the given item is in the bag. Otherwise it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at bag types, when more than one
--   element equivalent to the given item is in the bag. Otherwise it is
--   <i>unambiguous</i>.
lookupWithDefault :: Coll c a => a -> a -> c -> a

-- | Fold over all the elements in a collection in an unspecified order.
--   
--   <tt>fold f</tt> is <i>unambiguous</i> iff <tt>f</tt> is
--   fold-commutative.
fold :: Coll c a => (a -> b -> b) -> b -> c -> b

-- | A strict variant of <a>fold</a>.
--   
--   <tt>fold' f</tt> is <i>unambiguous</i> iff <tt>f</tt> 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.
--   
--   <tt>fold1 f</tt> is <i>unambiguous</i> iff <tt>f</tt> is
--   fold-commutative.
fold1 :: Coll c a => (a -> a -> a) -> c -> a

-- | A strict variant of <a>fold1</a>.
--   
--   <tt>fold1' f</tt> is <i>unambiguous</i> iff <tt>f</tt> is
--   fold-commutative.
fold1' :: Coll c a => (a -> a -> a) -> c -> a

-- | Remove all elements not satisfying the predicate.
--   
--   This function is always <i>unambiguous</i>.
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 <i>unambiguous</i>.
partition :: Coll c a => (a -> Bool) -> c -> (c, c)

-- | Similar to <a>strict</a>, this function walks the datastructure
--   forcing closures. However, <tt>strictWith</tt> will additionally apply
--   the given function to the collection elements, force the result using
--   <tt>seq</tt>, and then ignore it. This function can be used to perform
--   various levels of forcing on the sequence elements. In particular:
--   
--   <pre>
--   strictWith id xs
--   </pre>
--   
--   will force the spine of the datastructure and reduce each element to
--   WHNF.
--   
--   This function is always <i>unambiguous</i>.
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. <i>Note</i> that
--   <a>minView</a>, <a>minElem</a>, and <a>deleteMin</a> may make
--   different choices. Calls <a>fail</a> if the collection is empty.
--   
--   This function is <i>ambiguous</i> at bag types, if more than one
--   minimum element exists in the bag. Otherwise, it is
--   <i>unambiguous</i>.
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.
--   <i>Note</i> that <a>minView</a>, <a>minElem</a>, and <a>deleteMin</a>
--   may make different choices. Signals an error if the collection is
--   empty.
--   
--   This function is <i>ambiguous</i> at bag types, if more than one
--   minimum element exists in the bag. Otherwise, it is
--   <i>unambiguous</i>.
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. <i>Note</i> that
--   <a>maxView</a>, <a>maxElem</a> and <a>deleteMax</a> may make different
--   choices. Calls <a>fail</a> if the collection is empty.
--   
--   This function is <i>ambiguous</i> at bag types, if more than one
--   maximum element exists in the bag. Otherwise, it is
--   <i>unambiguous</i>.
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.
--   <i>Note</i> that <a>maxView</a>, <a>maxElem</a> and <a>deleteMax</a>
--   may make different choices. Signals an error if the collection is
--   empty.
--   
--   This function is <i>ambiguous</i> at bag types, if more than one
--   maximum element exists in the bag. Otherwise, it is
--   <i>unambiguous</i>.
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 <i>unambiguous</i> 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
--   <i>ambiguous</i>.
foldr :: OrdColl c a => (a -> b -> b) -> b -> c -> b

-- | A strict variant of <a>foldr</a>.
--   
--   This function is <i>unambiguous</i> 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
--   <i>ambiguous</i>.
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 <i>unambiguous</i> 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
--   <i>ambiguous</i>.
foldl :: OrdColl c a => (b -> a -> b) -> b -> c -> b

-- | A strict variant of <a>foldl</a>.
--   
--   This function is <i>unambiguous</i> 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
--   <i>ambiguous</i>.
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 <i>unambiguous</i> 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
--   <i>ambiguous</i>.
foldr1 :: OrdColl c a => (a -> a -> a) -> c -> a

-- | A strict variant of <a>foldr1</a>.
--   
--   This function is <i>unambiguous</i> 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
--   <i>ambiguous</i>.
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 <i>unambiguous</i> 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
--   <i>ambiguous</i>.
foldl1 :: OrdColl c a => (a -> a -> a) -> c -> a

-- | A strict variant of <a>foldl1</a>.
--   
--   This function is <i>unambiguous</i> 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
--   <i>ambiguous</i>.
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 <i>unambiguous</i>. At bag types, it is
--   <i>unambiguous</i> if no two equivalent elements exist in the bag;
--   otherwise it is <i>ambiguous</i>.
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:
--   
--   <pre>
--   forall x y. x &lt; y ==&gt; f x &lt; f y
--   </pre>
--   
--   This function is <i>unambiguous</i>, 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 <a>Eq</a> instance on the elements.
--   
--   <i>WARNING: Each of the following "With" functions is unsafe.</i> 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 <tt>x == y == z</tt>, then <tt>fromSeqWith (+)
--   [x,y,z]</tt> equals either <tt>single (x + (y + z))</tt> or <tt>single
--   ((x + y) + z)</tt>
class (Coll c a, SetX c a) => Set c a | c -> a

-- | Same as <a>fromSeq</a> but with a combining function to resolve
--   duplicates.
--   
--   This function is <i>unambiguous</i> under the "with" precondition if
--   the combining function is associative. Otherwise it is
--   <i>ambiguous</i>.
fromSeqWith :: (Set c a, Sequence seq) => (a -> a -> a) -> seq a -> c

-- | Same as <a>insert</a> but with a combining function to resolve
--   duplicates.
--   
--   This function is <i>unambiguous</i> under the "with" precondition.
insertWith :: Set c a => (a -> a -> a) -> a -> c -> c

-- | Same as <a>insertSeq</a> but with a combining function to resolve
--   duplicates.
--   
--   This function is <i>unambiguous</i> under the "with" precondition if
--   the combining function is associative. Otherwise it is
--   <i>ambiguous</i>.
insertSeqWith :: (Set c a, Sequence seq) => (a -> a -> a) -> seq a -> c -> c

-- | Left biased union.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>unionl = unionWith (\x y -&gt; x)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
unionl :: Set c a => c -> c -> c

-- | Right biased union.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>unionr = unionWith (\x y -&gt; y)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
unionr :: Set c a => c -> c -> c

-- | Same as <a>union</a>, but with a combining function to resolve
--   duplicates.
--   
--   This function is <i>unambiguous</i> under the "with" precondition.
unionWith :: Set c a => (a -> a -> a) -> c -> c -> c

-- | Same as <a>unionSeq</a>, but with a combining function to resolve
--   duplicates.
--   
--   This function is <i>unambiguous</i> under the "with" precondition if
--   the combining function is associative. Otherwise it is
--   <i>ambiguous</i>.
unionSeqWith :: (Set c a, Sequence seq) => (a -> a -> a) -> seq (c) -> c

-- | Same as <a>intersection</a>, but with a combining function to resolve
--   duplicates.
--   
--   This function is <i>unambiguous</i> 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:
--   
--   <pre>
--   (OrdColl c a,Set c a)
--   </pre>
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:
--   
--   <pre>
--   forall x y. x &lt; y ==&gt; f x &lt; f y
--   </pre>
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 <a>union</a>.
unionMap :: (Coll cin a, CollX cout b) => (a -> cout) -> (cin -> cout)


-- | The <i>associative collection</i> 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 <a>Functor</a> as a superclass of every
--   associative collection. See <a>Data.Edison.Coll</a> 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
--   <i>unambiguous</i> with respect to the key storage behavior, but that
--   methods which can observe keys are <i>ambiguous</i> with respect to
--   the actual keys returned.
--   
--   In all cases where an operation is ambiguous with respect to the key,
--   the operation is rendered <i>unambiguous</i> if the <tt>Eq</tt>
--   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 <tt>fmap</tt> from <tt>Functor</tt>.
--   
--   This function is always <i>unambiguous</i>.
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 <i>unambiguous</i>.
empty :: AssocX m k => m a

-- | Create an associative collection with a single binding.
--   
--   This function is always <i>unambiguous</i>.
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 <i>ambiguous</i> at finite map types if the sequence
--   contains more than one equivalent key. Otherwise it is
--   <i>unambiguous</i>.
fromSeq :: (AssocX m k, Sequence seq) => seq (k, a) -> m a

-- | Add a binding to an associative collection. For finite maps,
--   <a>insert</a> keeps the new element in the case of duplicate keys.
--   
--   This function is <i>unambiguous</i>.
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 <i>ambiguous</i> at finite map types if the sequence
--   contains more than one equivalent key. Otherwise it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at finite map types if the map keys
--   are not disjoint. Otherwise it is <i>unambiguous</i>.
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 <i>ambiguous</i> at finite map types if the map keys
--   are not mutually disjoint. Otherwise it is <i>unambiguous</i>.
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 <i>ambiguous</i> at finite relation types if the key
--   appears more than once in the relation. Otherwise it is
--   <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>ambiguous</i> 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 <i>unambiguous</i>.
deleteSeq :: (AssocX m k, Sequence seq) => seq k -> m a -> m a

-- | Test whether the associative collection is empty.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>null m = (size m == 0)</pre></li>
--   </ul>
--   
--   This function is always <i>unambiguous</i>.
null :: AssocX m k => m a -> Bool

-- | Return the number of bindings in the associative collection.
--   
--   This function is always <i>unambiguous</i>.
size :: AssocX m k => m a -> Int

-- | Test whether the given key is bound in the associative collection.
--   
--   This function is always <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>ambiguous</i> at finite relation types if the key
--   appears more than once in the finite relation. Otherwise, it is
--   <i>unambiguous</i>.
lookup :: AssocX m k => k -> m a -> a

-- | Find the element associated with the given key. Calls <a>fail</a> 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 <i>ambiguous</i> at finite relation types if the key
--   appears more than once in the finite relation. Otherwise, it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at finite relation types if the key
--   appears more than once in the finite relation. Otherwise, it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at finite relation types if the key
--   appears more than once in the finite relation. Otherwise, it is
--   <i>unambiguous</i>.
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 <tt>fail</tt> 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 <i>ambiguous</i> at finite relation types if the key
--   appears more than once in the finite relation. Otherwise, it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at finite relation types if the key
--   appears more than once in the finite relation. Otherwise, it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at finite relation types if the key
--   appears more than once in the finite relation. Otherwise, it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at finite relation types if the key
--   appears more than once in the finite relation. Otherwise, it is
--   <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>ambiguous</i> at finite relation types if the key
--   appears more than once in the finite relation. Otherwise, it is
--   <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <tt>Nothing</tt>,
--   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 <i>ambiguous</i> at finite relation types if the key
--   appears more than once in the finite relation. Otherwise, it is
--   <i>unambiguous</i>.
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
--   <tt>Nothing</tt>, the corresponding binding is deleted. If the key is
--   not found in the collection, it is returned unchanged.
--   
--   This function is always <i>unambiguous</i>.
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. <i>Note</i> that <a>fold</a> ignores the keys.
--   
--   <tt>fold f</tt> is <i>unambiguous</i> iff <tt>f</tt> is
--   fold-commutative.
fold :: AssocX m k => (a -> b -> b) -> b -> m a -> b

-- | A strict variant of <a>fold</a>.
--   
--   <tt>fold' f</tt> is <i>unambiguous</i> iff <tt>f</tt> 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 <tt>reduce1</tt> on sequences).
--   <i>Note</i> that <a>fold1</a> ignores the keys.
--   
--   <tt>fold1 f</tt> is <i>unambiguous</i> iff <tt>f</tt> is
--   fold-commutative.
fold1 :: AssocX m k => (a -> a -> a) -> m a -> a

-- | A strict variant of <a>fold1</a>.
--   
--   <tt>fold1' f</tt> is <i>unambiguous</i> iff <tt>f</tt> 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 <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>ambiguous</i> 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 <tt>strict</tt> will
--   result in bottom. Operationally, this function walks the datastructure
--   forcing any closures. Elements contained in the map are <i>not</i>
--   forced.
--   
--   This function is always <i>unambiguous</i>.
strict :: AssocX m k => m a -> m a

-- | Similar to <a>strict</a>, this function walks the datastructure
--   forcing closures. However, <tt>strictWith</tt> will additionally apply
--   the given function to the map elements, force the result using
--   <tt>seq</tt>, and then ignore it. This function can be used to perform
--   various levels of forcing on the sequence elements. In particular:
--   
--   <pre>
--   strictWith id xs
--   </pre>
--   
--   will force the spine of the datastructure and reduce each element to
--   WHNF.
--   
--   This function is always <i>unambiguous</i>.
strictWith :: AssocX m k => (a -> b) -> m a -> m a

-- | A method to facilitate unit testing. Returns <a>True</a> if the
--   structural invariants of the implementation hold for the given
--   associative collection. If this function returns <a>False</a>, 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 <a>fail</a>
--   if the associative collection is empty. Which binding is removed if
--   there is more than one minimum is unspecified.
--   
--   This function is <i>ambiguous</i> at finite relation types if the
--   finite relation contains more than one minimum key. Otherwise it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at finite relation types if the
--   finite relation contains more than one minimum key. Otherwise it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at finite relation types if the
--   finite relation contains more than one minimum key. Otherwise it is
--   <i>unambiguous</i>.
deleteMin :: OrdAssocX m k => m a -> m a

-- | Insert a binding into an associative collection with the precondition
--   that the given key is <tt>&lt;=</tt> any existing keys already in the
--   collection. For finite maps, this precondition is strengthened to
--   <tt>&lt;</tt>.
--   
--   This function is <i>unambiguous</i> 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 <a>fail</a>
--   if the associative collection is empty. Which binding is removed if
--   there is more than one maximum is unspecified.
--   
--   This function is <i>ambiguous</i> at finite relation types if the
--   finite relation contains more than one minimum key. Otherwise it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at finite relation types if the
--   finite relation contains more than one minimum key. Otherwise it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at finite relation types if the
--   finite relation contains more than one minimum key. Otherwise it is
--   <i>unambiguous</i>.
deleteMax :: OrdAssocX m k => m a -> m a

-- | Insert a binding into an associative collection with the precondition
--   that the given key is <tt>&gt;=</tt> any existing keys already in the
--   collection. For finite maps, this precondition is strengthened to
--   <tt>&gt;</tt>.
--   
--   This function is <i>unambiguous</i> 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.
--   
--   <tt>foldr f</tt> is <i>unambiguous</i> if <tt>f</tt> is
--   fold-commutative, at finite map types, or at finite relation types if
--   the relation contains no duplicate keys. Otherwise it is
--   <i>ambiguous</i>.
foldr :: OrdAssocX m k => (a -> b -> b) -> b -> m a -> b

-- | A strict variant of <a>foldr</a>.
--   
--   <tt>foldr' f</tt> is <i>unambiguous</i> if <tt>f</tt> is
--   fold-commutative, at finite map types, or at finite relation types if
--   the relation contains no duplicate keys. Otherwise it is
--   <i>ambiguous</i>.
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.
--   
--   <tt>foldl f</tt> is <i>unambiguous</i> if <tt>f</tt> is
--   fold-commutative, at finite map types, or at finite relation types if
--   the relation contains no duplicate keys. Otherwise it is
--   <i>ambiguous</i>.
foldl :: OrdAssocX m k => (b -> a -> b) -> b -> m a -> b

-- | A strict variant of <a>foldl</a>.
--   
--   <tt>foldl' f</tt> is <i>unambiguous</i> if <tt>f</tt> is
--   fold-commutative, at finite map types, or at finite relation types if
--   the relation contains no duplicate keys. Otherwise it is
--   <i>ambiguous</i>.
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.
--   
--   <tt>foldr1 f</tt> is <i>unambiguous</i> if <tt>f</tt> is
--   fold-commutative, at finite map types, or at finite relation types if
--   the relation contains no duplicate keys. Otherwise it is
--   <i>ambiguous</i>.
foldr1 :: OrdAssocX m k => (a -> a -> a) -> m a -> a

-- | A strict variant of <a>foldr1</a>.
--   
--   <tt>foldr1' f</tt> is <i>unambiguous</i> if <tt>f</tt> is
--   fold-commutative, at finite map types, or at finite relation types if
--   the relation contains no duplicate keys. Otherwise it is
--   <i>ambiguous</i>.
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.
--   
--   <tt>foldl1 f</tt> is <i>unambiguous</i> if <tt>f</tt> is
--   fold-commutative, at finite map types, or at finite relation types if
--   the relation contains no duplicate keys. Otherwise it is
--   <i>ambiguous</i>.
foldl1 :: OrdAssocX m k => (a -> a -> a) -> m a -> a

-- | A strict variant of <a>foldl1</a>.
--   
--   <tt>foldl1' f</tt> is <i>unambiguous</i> if <tt>f</tt> is
--   fold-commutative, at finite map types, or at finite relation types if
--   the relation contains no duplicate keys. Otherwise it is
--   <i>ambiguous</i>.
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 <i>unambiguous</i> 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 <tt>&lt;=</tt> every key in the
--   second associative collection. For finite maps, this precondition is
--   strengthened to <tt>&lt;</tt>.
--   
--   This function is <i>unambiguous</i> under the precondition.
unsafeAppend :: OrdAssocX m k => m a -> m a -> m a

-- | Extract all bindings whose keys are <tt>&lt;</tt> the given key.
--   
--   This function is always <i>unambiguous</i>.
filterLT :: OrdAssocX m k => k -> m a -> m a

-- | Extract all bindings whose keys are <tt>&lt;=</tt> the given key.
--   
--   This function is always <i>unambiguous</i>.
filterLE :: OrdAssocX m k => k -> m a -> m a

-- | Extract all bindings whose keys are <tt>&gt;</tt> the given key.
--   
--   This function is always <i>unambiguous</i>.
filterGT :: OrdAssocX m k => k -> m a -> m a

-- | Extract all bindings whose keys are <tt>&gt;=</tt> the given key.
--   
--   This function is always <i>unambiguous</i>.
filterGE :: OrdAssocX m k => k -> m a -> m a

-- | Split an associative collection into two sub-collections, containing
--   those bindings whose keys are <tt>&lt;</tt> the given key and those
--   which are <tt>&gt;=</tt>.
--   
--   This function is always <i>unambiguous</i>.
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 <tt>&lt;=</tt> the given key and those
--   which are <tt>&gt;</tt>.
--   
--   This function is always <i>unambiguous</i>.
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 <tt>&lt;</tt> the given key and those
--   which are <tt>&gt;</tt>. All bindings with keys equal to the given key
--   are discarded.
--   
--   This function is always <i>unambiguous</i>.
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 <a>fromSeq</a>, but with a combining function to resolve
--   duplicates.
--   
--   This function is always <i>unambiguous</i>.
fromSeqWith :: (FiniteMapX m k, Sequence seq) => (a -> a -> a) -> seq (k, a) -> m a

-- | Same as <a>fromSeq</a>, but with a combining function to resolve
--   duplicates; the combining function takes the key in addition to the
--   two elements.
--   
--   This function is always <i>unambiguous</i>.
fromSeqWithKey :: (FiniteMapX m k, Sequence seq) => (k -> a -> a -> a) -> seq (k, a) -> m a

-- | Same as <a>insert</a>, but with a combining function to resolve
--   duplicates.
--   
--   This function is <i>unambiguous</i>.
insertWith :: FiniteMapX m k => (a -> a -> a) -> k -> a -> m a -> m a

-- | Same as <a>insert</a>, 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 <i>unambiguous</i>.
insertWithKey :: FiniteMapX m k => (k -> a -> a -> a) -> k -> a -> m a -> m a

-- | Same as <a>insertSeq</a>, but with a combining function to resolve
--   duplicates.
--   
--   This function is <i>unambiguous</i>.
insertSeqWith :: (FiniteMapX m k, Sequence seq) => (a -> a -> a) -> seq (k, a) -> m a -> m a

-- | Same as <a>insertSeq</a>, but with a combining function to resolve
--   duplicates; the combining function takes the key in addition to the
--   two elements.
--   
--   This function is <i>unambiguous</i>.
insertSeqWithKey :: (FiniteMapX m k, Sequence seq) => (k -> a -> a -> a) -> seq (k, a) -> m a -> m a

-- | Left biased union.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>unionl = unionwith (\x y -&gt; x)</pre></li>
--   </ul>
--   
--   This function is <i>unambiguous</i>.
unionl :: FiniteMapX m k => m a -> m a -> m a

-- | Right biased union.
--   
--   <i>Axioms:</i>
--   
--   <ul>
--   <li><pre>unionr = unionWith (\x y -&gt; y)</pre></li>
--   </ul>
--   
--   This function is <i>unambiguous</i>.
unionr :: FiniteMapX m k => m a -> m a -> m a

-- | Same as <a>union</a>, but with a combining function to resolve
--   duplicates.
--   
--   This function is <i>unambiguous</i>.
unionWith :: FiniteMapX m k => (a -> a -> a) -> m a -> m a -> m a

-- | Same as <a>unionSeq</a>, but with a combining function to resolve
--   duplicates.
--   
--   This function is <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>unambiguous</i>.
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 <i>ambiguous</i> with respect to the sequence order
--   iff the associative collection contains more than one binding.
--   Furthermore, it is <i>ambiguous</i> with respect to the actual key
--   returned, unless the <tt>Eq</tt> 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 <i>ambiguous</i> with respect to the sequence order
--   iff the associative collection contains more than one binding.
--   Furthermore, it is <i>ambiguous</i> with respect to the actual key
--   returned, unless the <tt>Eq</tt> 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 <i>ambiguous</i> with respect to the actual keys
--   observed, unless the <tt>Eq</tt> 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.
--   
--   <tt>foldWithKey f</tt> is <i>unambiguous</i> iff <tt>f</tt> is
--   fold-commutative and the <tt>Eq</tt> instance on keys corresponds to
--   indistinguisability.
foldWithKey :: Assoc m k => (k -> a -> b -> b) -> b -> m a -> b

-- | A strict variant of <a>foldWithKey</a>.
--   
--   <tt>foldWithKey' f</tt> is <i>unambiguous</i> iff <tt>f</tt> is
--   fold-commutative and the <tt>Eq</tt> 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 <i>ambiguous</i> with respect to the actual keys
--   observed, unless the <tt>Eq</tt> 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 <i>ambiguous</i> with respect to the actual keys
--   observed, unless the <tt>Eq</tt> 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 <a>fail</a> if the associative collection is empty.
--   Which binding is chosen if there are multiple minimum keys is
--   unspecified.
--   
--   This function is <i>ambiguous</i> at finite relation types if more
--   than one minimum key exists in the relation. Furthermore, it is
--   <i>ambiguous</i> with respect to the actual key observed unless the
--   <tt>Eq</tt> 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 <i>ambiguous</i> at finite relation types if more
--   than one minimum key exists in the relation. Furthermore, it is
--   <i>ambiguous</i> with respect to the actual key observed unless the
--   <tt>Eq</tt> 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 <a>fail</a> if the associative collection is empty.
--   Which binding is chosen if there are multiple maximum keys is
--   unspecified.
--   
--   This function is <i>ambiguous</i> at finite relation types if more
--   than one maximum key exists in the relation. Furthermore, it is
--   <i>ambiguous</i> with respect to the actual key observed unless the
--   <tt>Eq</tt> 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 <i>ambiguous</i> at finite relation types if more
--   than one maximum key exists in the relation. Furthermore, it is
--   <i>ambiguous</i> with respect to the actual key observed unless the
--   <tt>Eq</tt> 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.
--   
--   <tt>foldrWithKey f</tt> is <i>ambiguous</i> at finite relation types
--   if the relation contains more than one equivalent key and <tt>f</tt>
--   is not fold-commutative OR if the <tt>Eq</tt> instance on keys does
--   not correspond to indistingusihability.
foldrWithKey :: OrdAssoc m k => (k -> a -> b -> b) -> b -> m a -> b

-- | A strict variant of <a>foldrWithKey</a>.
--   
--   <tt>foldrWithKey' f</tt> is <i>ambiguous</i> at finite relation types
--   if the relation contains more than one equivalent key and <tt>f</tt>
--   is not fold-commutative OR if the <tt>Eq</tt> instance on keys does
--   not correspond to indistingusihability. Otherwise it is
--   <i>unambiguous</i>.
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.
--   
--   <tt>foldlWithKey f</tt> is <i>ambiguous</i> at finite relation types
--   if the relation contains more than one equivalent key and <tt>f</tt>
--   is not fold-commutative OR if the <tt>Eq</tt> instance on keys does
--   not correspond to indistingusihability. Otherwise it is
--   <i>unambiguous</i>.
foldlWithKey :: OrdAssoc m k => (b -> k -> a -> b) -> b -> m a -> b

-- | A strict variant of <a>foldlWithKey</a>.
--   
--   <tt>foldlWithKey' f</tt> is <i>ambiguous</i> at finite relation types
--   if the relation contains more than one equivalent key and <tt>f</tt>
--   is not fold-commutative OR if the <tt>Eq</tt> instance on keys does
--   not correspond to indistinguishability. Otherwise it is
--   <i>unambiguous</i>.
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 <i>ambiguous</i> at finite relation types if the
--   relation contains more than one equivalent key, or if the <tt>Eq</tt>
--   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 <a>union</a>, 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 <i>unambiguous</i> provided that the <tt>Eq</tt>
--   instance on keys corresponds to indistinguishability.
unionWithKey :: FiniteMap m k => (k -> a -> a -> a) -> m a -> m a -> m a

-- | Same as <a>unionSeq</a>, 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 <i>unambiguous</i> provided that the <tt>Eq</tt>
--   instance on keys corresponds to indistinguishability.
unionSeqWithKey :: (FiniteMap m k, Sequence seq) => (k -> a -> a -> a) -> seq (m a) -> m a

-- | Same as <a>intersectionWith</a>, 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 <i>unambiguous</i> provided the <tt>Eq</tt> 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 <a>submapBy</a> where the comparison function is
--   given by <tt>(==)</tt>.
submap :: (Eq a, FiniteMapX m k) => m a -> m a -> Bool

-- | Specialization of <a>properSubmapBy</a> where the comparison function
--   is given by <tt>(==)</tt>.
properSubmap :: (Eq a, FiniteMapX m k) => m a -> m a -> Bool

-- | Specialization of <a>sameMapBy</a> where the comparison function is
--   given by <tt>(==)</tt>.
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 <tt>(++)</tt> will
--   conflict with the Prelude definition. Either this definition or the
--   Prelude definition will need to be imported <tt>hiding ( (++) )</tt>.
--   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 <a>lcons</a>.
(<|) :: Sequence seq => a -> seq a -> seq a

-- | Right (rear) cons on a sequence. The new element appears on the right.
--   Identical to <a>rcons</a> with reversed arguments.
(|>) :: Sequence seq => seq a -> a -> seq a

-- | Append two sequences. Identical to <a>append</a>. Subsumes the Prelude
--   definition.
(++) :: Sequence seq => seq a -> seq a -> seq a

-- | Lookup an element in a sequence. Identical to <a>lookup</a> with
--   reversed arguments.
(!) :: Sequence seq => seq a -> Int -> a

-- | Subset test operation. Identical to <a>subset</a>.
(|=) :: SetX set a => set -> set -> Bool

-- | Set difference. Identical to <a>difference</a>.
(\\) :: SetX set a => set -> set -> set

-- | Set intersection. Identical to <a>intersection</a>.
(/\) :: SetX set a => set -> set -> set

-- | Set union. Identical to <a>union</a>.
(\/) :: 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 <i>ED</i>i<i>S</i>on (<i>E</i>fficent <i>D</i>ata
--   <i>S</i>tructures).
--   
--   Edison provides several families of abstractions, each with multiple
--   implementations. The main abstractions provided by Edison are:
--   
--   <ul>
--   <li><i>Sequences</i> such as stacks, queues, and dequeues,</li>
--   <li><i>Collections</i> such as sets, bags and heaps, and</li>
--   <li><i>Associative Collections</i> such as finite maps and priority
--   queues where the priority and element are distinct.</li>
--   </ul>
--   
--   <i>Conventions:</i>
--   
--   Each data structure is implemented as a separate module. These modules
--   should always be imported <tt>qualified</tt> to prevent a flood of
--   name clashes, and it is recommended to rename the module using the
--   <tt>as</tt> 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, <tt>empty</tt>, <tt>null</tt>, <tt>size</tt>, etc).
--   It also means that in many cases names have been reused from the
--   Prelude. However, the use of <tt>qualified</tt> 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 <tt>hiding</tt> the relevant names.
--   
--   Edison modules also frequently share type names. For example, most
--   sequence type constructors are named <tt>Seq</tt>. This additionally
--   aids substituting implementations by simply importing a different
--   module.
--   
--   Argument orders are selected with the following points in mind:
--   
--   <ul>
--   <li><i>Partial application:</i> arguments more likely to be static
--   usually appear before other arguments in order to facilitate partial
--   application.</li>
--   <li><i>Collection appears last:</i> in all cases where an operation
--   queries a single collection or modifies an existing collection, the
--   collection argument will appear last. This is something of a de facto
--   standard for Haskell datastructure libraries and lends a degree of
--   consistency to the API.</li>
--   <li><i>Most usual order:</i> where an operation represents a
--   well-known mathematical function on more than one datastructure, the
--   arguments are chosen to match the most usual argument order for the
--   function.</li>
--   </ul>
--   
--   <i>Type classes:</i>
--   
--   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 <a>Data.Edison.Seq</a>, <a>Data.Edison.Coll</a>
--   and <a>Data.Edison.Assoc</a>. 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.
--   
--   <i>Notes on Eq and Ord instances:</i>
--   
--   Many Edison data structures require <tt>Eq</tt> or <tt>Ord</tt>
--   contexts to define equivalence and total ordering on elements or keys.
--   Edison makes the following assumptions about all such required
--   instances:
--   
--   <ul>
--   <li>An <tt>Eq</tt> instance correctly defines an equivalence relation
--   (but not necessarily structural equality); that is, we assume
--   <tt>(==)</tt> (considered as a relation) is reflexive, symmetric and
--   transitive, but allow that equivalent items may be distinguishable by
--   other means.</li>
--   <li>An <tt>Ord</tt> instance correctly defines a total order which is
--   consistent with the <tt>Eq</tt> instance for that type.</li>
--   </ul>
--   
--   These assumptions correspond to the usual meanings assigned to these
--   classes. If an Edison data structure is used with an <tt>Eq</tt> or
--   <tt>Ord</tt> instance which violates these assumptions, then the
--   behavior of that data structure is undefined.
--   
--   <i>Notes on Read and Show instances:</i>
--   
--   The usual Haskell convention for <tt>Read</tt> and <tt>Show</tt>
--   instances (as championed by the Haskell "deriving" mechanism), is that
--   <tt>show</tt> 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 <tt>Read</tt> instances are able
--   to parse such strings, such that <tt>(read . show) === id</tt>. So,
--   derived instances of <tt>Read</tt> and <tt>Show</tt> exhibit the
--   following useful properties:
--   
--   <ul>
--   <li><tt>read</tt> and <tt>show</tt> are complementary; that is,
--   <tt>read</tt> is a useful inverse for <tt>show</tt></li>
--   <li><tt>show</tt> generates a string which is legal Haskell code
--   representing the data item</li>
--   </ul>
--   
--   For concrete data types, the deriving mechanism is usually quite
--   sufficient. However, for abstract types the derived <tt>Read</tt>
--   instance may allow users to create data which violates invariants.
--   Furthermore, the strings resulting from <tt>show</tt> 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
--   <tt>Read</tt> instance strips the list conversion call before parsing
--   the list. In this way, private data constructors are not revealed and
--   <tt>show</tt> strings are still legal, compilable Haskell code.
--   Furthermore, the showed strings gain a degree of independence from the
--   underlying datastructure implementation.
--   
--   For example, calling <tt>show</tt> on an empty Banker's queue will
--   result in the following string:
--   
--   <pre>
--   Data.Edison.Seq.BankersQueue.fromList []
--   </pre>
--   
--   Datatypes which are not native Edison data structures (such as
--   StandardSet and StandardMap) may or may not provide <tt>Read</tt> or
--   <tt>Show</tt> instances and, if they exist, they may or may not also
--   provide the properties that Edison native <tt>Read</tt> and
--   <tt>Show</tt> instances do.
--   
--   <i>Notes on time complexities:</i>
--   
--   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. <i>Efficient Data Structures in a Lazy Functional
--   Language</i>. Master's Thesis. Chalmers University of Technology,
--   Sweden. 2003.
--   
--   <i>Notes on unsafe functions:</i>
--   
--   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
--   <tt>unsafePerformIO</tt> or <tt>unsafeCoerce#</tt>. 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 <tt>unsafe</tt> prefix. An exception to this rule is the
--   <tt>With</tt> functions in the <a>Set</a> class, which are also unsafe
--   but do not have the prefix. Unsafe functions will have explicit
--   preconditions listed in their documentation.
--   
--   <i>Notes on ambiguous functions:</i>
--   
--   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 <a>AssocX</a> class contains the
--   <tt>fold</tt> function, which folds over the elements in the
--   collection in an arbitrary order. If the combining function passed to
--   <tt>fold</tt> 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 <i>ambiguous</i> or
--   <i>unambiguous</i> 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 <tt>unsafePerformIO</tt> 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.
--   
--   <i>How to choose a fold:</i>
--   
--   <i>Folds</i> 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
--   <i>fewest</i> 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 <tt>fold</tt>
--   (which does not guarantee an order) over <tt>foldl</tt> or
--   <tt>foldr</tt>, which specify particular orders.
--   
--   Also, if your function is strict in the accumulating argument, you
--   should prefer the strict folds (eg, <tt>fold'</tt>); they will often
--   provide better space behavior. <i>Be aware</i>, however, that the
--   "strict" folds are not <i>necessarily</i> 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 <tt>WithKey</tt> folds if
--   you actually need the value of the key.
--   
--   <i>Painfully detailed information about ambiguous folds:</i>
--   
--   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 <tt>f :: a -&gt; b -&gt; b</tt> is <i>fold-commutative</i> iff
--   <tt>f</tt> is unambiguous and
--   
--   <pre>
--   forall w, z :: b; m, n :: a
--   
--      w = z ==&gt; f m (f n w) = f n (f m z)
--   </pre>
--   
--   where <tt>=</tt> 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 <i>unambiguous</i>.
--   
--   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 <tt>g
--   :: b -&gt; a -&gt; b</tt> is fold commutative iff <tt>flip g :: a
--   -&gt; b -&gt; b</tt> 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 <tt>g :: k -&gt; a
--   -&gt; b -&gt; b</tt> is fold commutative iff
--   
--   <pre>
--   \(k,x) z -&gt; g k x z :: (k,a) -&gt; b -&gt; b
--   </pre>
--   
--   is fold commutative according to the above definition.
--   
--   Note that for <tt>g :: a -&gt; a -&gt; a</tt>, if <tt>g</tt> is
--   unambiguous, commutative, and associative, then <tt>g</tt> is
--   fold-commutative.
--   
--   Proof:
--   
--   <pre>
--   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
--   </pre>
--   
--   Qed.
--   
--   Thus, many common numeric combining functions, including <tt>(+)</tt>
--   and <tt>(*)</tt> at integral types, are fold commutative and can be
--   safely used with ambiguous folds.
--   
--   <i>Be aware</i> however, that <tt>(+)</tt> and <tt>(*)</tt> at
--   floating point types are only <i>approximately</i> 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.
--   
--   <i>About this module:</i>
--   
--   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 <tt>qualified</tt>. 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
--   <a>Data.Edison.Prelude</a> module.
--   
--   <i>Miscellaneous points:</i>
--   
--   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 <a>Data.Edison.Sym</a> 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 <a>Sequence</a> 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
--   <a>Eq</a> 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
--   <tt>(OrdCollX c a,SetX c a)</tt>.
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 <a>Eq</a> instance on the elements.
--   
--   <i>WARNING: Each of the following "With" functions is unsafe.</i> 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 <tt>x == y == z</tt>, then <tt>fromSeqWith (+)
--   [x,y,z]</tt> equals either <tt>single (x + (y + z))</tt> or <tt>single
--   ((x + y) + z)</tt>
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:
--   
--   <pre>
--   (OrdColl c a,Set c a)
--   </pre>
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
