Copyright | Copyright (c) 1998 Chris Okasaki |
---|---|

License | MIT; see COPYRIGHT file for terms and conditions |

Maintainer | robdockins AT fastmail DOT fm |

Stability | stable |

Portability | GHC, Hugs (MPTC and FD) |

Safe Haskell | Safe |

Language | Haskell2010 |

The *collection* abstraction includes sets, bags and priority queues
(heaps). Collections are defined in Edison as a set of eight classes.

All collections assume at least an equality relation of elements, and may also assume an ordering relation.

The hierarchy contains a root class `CollX`

together with seven
subclasses satisfying one or more of three common sub-properties:

*Uniqueness*Each element in the collection is unique (no two elements in the collection are equal). These subclasses, indicated by the name`Set`

, represent sets rather than bags (multi-sets).*Ordering*The elements have a total ordering and it is possible to process the elements in non-decreasing order. These subclasses, indicates by the`Ord`

prefix, typically represent either priority queues (heaps) or sets/bags implemented as binary search trees.*Observability*An observable collection is one in which it is possible to view the elements in a collection. The`X`

suffix indicates a lack of observability. This property is discussed is greater detail below.

Because collections encompass a wide range of abstractions, there is no
single name that is suitable for all collection type constructors.
However, most modules implementing collections will define a type
constructor named either `Bag`

, `Set`

, or `Heap`

.

*Notes on observability*

Note that the equality relation defined by the `Eq`

class is not
necessarily true equality. Very often it is merely an equivalence
relation, where two equivalent values may be distinguishable by other
means. For example, we might consider two binary trees to be equal
if they contain the same elements, even if their shapes are different.

Because of this phenomenon, implementations of observable collections
(ie, collections where it is possible to inspect the elements) are rather
constrained. Such an implementation must retain the actual elements that
were inserted. For example, it is not possible in general to represent an
observable bag as a finite map from elements to counts, because even if we
know that a given bag contains, say, three elements from some equivalence
class, we do not necessarily know *which* three.

On the other hand, implementations of *non-observable* collections have
much greater freedom to choose abstract representations of each
equivalence class. For example, representing a bag as a finite map from
elements to counts works fine if we never need to know *which*
representatives from an equivalence class are actually present. As
another example, consider the `UniqueHash`

class defined in
Data.Edison.Prelude. If we know that the `hash`

function yields a
unique integer for each equivalence class, then we can represent a
collection of hashable elements simply as a collection of integers. With
such a representation, we can still do many useful things like testing for
membership; we just can't support functions like `fold`

or `filter`

that
require the elements themselves, rather than the hashed values.

- empty :: CollX c a => c
- union :: CollX c a => c -> c -> c
- class (Eq a, Monoid c) => CollX c a | c -> a where
- class (CollX c a, Ord a) => OrdCollX c a | c -> a where
- class CollX c a => SetX c a | c -> a where
- class (OrdCollX c a, SetX c a) => OrdSetX c a | c -> a
- class CollX c a => Coll c a | c -> a where
- class (Coll c a, OrdCollX c a) => OrdColl c a | c -> a where
- class (Coll c a, SetX c a) => Set c a | c -> a where
- 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

# Superclass aliases

## Monoid

empty :: CollX c a => c Source #

The empty collection. Equivalant to `mempty`

from
the `Monoid`

instance.

This function is always *unambiguous*.

union :: CollX c a => c -> c -> c Source #

Merge two collections. For sets, it is unspecified which element is
kept in the case of duplicates. Equivalant to `mappend`

from the
`Monoid`

instance.

This function is *ambiguous* at set types if the sets are not disjoint.
Otherwise it is *unambiguous*.

# Non-observable collections

class (Eq a, Monoid c) => CollX c a | c -> a where Source #

This is the root class of the collection hierarchy. However, it is perfectly adequate for many applications that use sets or bags.

singleton, fromSeq, unionSeq, insert, insertSeq, delete, deleteAll, deleteSeq, null, size, member, count, strict, structuralInvariant, instanceName

create a singleton collection

This function is always *unambiguous*.

fromSeq :: Sequence seq => seq a -> c Source #

Convert a sequence to a collection. For sets, it is unspecified which element is kept in case of duplicates.

This function is *ambiguous* at set types if more than one
equivalent item is in the sequence. Otherwise it is *unambiguous*.

unionSeq :: Sequence seq => seq c -> c Source #

Merge a sequence of collections. For sets, it is unspecified which element is kept in the case of duplicates.

This function is *ambiguous* at set types if the sets in the sequence
are not mutually disjoint. Otherwise it is *unambiguous*.

insert :: a -> c -> c Source #

Insert an element into a collection. For sets, if an equal element is already in the set, the newly inserted element is kept, and the old element is discarded.

This function is always *unambiguous*.

insertSeq :: Sequence seq => seq a -> c -> c Source #

Insert a sequence of elements into a collection. For sets, the behavior with regard to multiple equal elements is unspecified.

This function is *ambiguous* at set types if the sequence contains
more than one equivalent item or an item which is already in the set.
Otherwise it is *unambiguous*.

delete :: a -> c -> c Source #

Delete a single occurrence of the given element from a collection. For bags, it is unspecified which element will be deleted.

This function is *ambiguous* at bag types if more than one item exists
in the bag equivalent to the given item. Otherwise it is *unambiguous*.

deleteAll :: a -> c -> c Source #

Delete all occurrences of an element from a collection. For sets
this operation is identical to `delete`

.

This function is always *unambiguous*.

deleteSeq :: Sequence seq => seq a -> c -> c Source #

Delete a single occurrence of each of the given elements from a collection. For bags, there may be multiple occurrences of a given element in the collection, in which case it is unspecified which is deleted.

This function is *ambiguous* at bag types if more than one item
exists in the bag equivalent to any item in the list and the number
of equivalent occurrences of that item in the sequence is less than
the number of occurrences in the bag. Otherwise it is *unambiguous*.

Test whether the collection is empty.

*Axioms:*

null xs = (size xs == 0)

This function is always *unambiguous*.

Return the number of elements in the collection.

This function is always *unambiguous*.

member :: a -> c -> Bool Source #

Test whether the given element is in the collection.

*Axioms:*

member x xs = (count x xs > 0)

This function is always *unambiguous*.

count :: a -> c -> Int Source #

Count how many copies of the given element are in the collection. For sets, this will always return 0 or 1.

This function is always *unambiguous*.

Semanticly, this function is a partial identity function. If the
datastructure is infinite in size or contains exceptions or non-termination
in the structure itself, then `strict`

will result in bottom. Operationally,
this function walks the datastructure forcing any closures. In many
collections, the collction "shape" depends on the value of the elemnts;
in such cases, the values of the elements will be forced to the extent
necessary to force the structure of the collection, but no further.

This function is always *unambiguous*.

structuralInvariant :: c -> Bool Source #

A method to facilitate unit testing. Returns `True`

if the structural
invariants of the implementation hold for the given collection. If
this function returns `False`

, it represents a bug; generally, either
the implementation itself is flawed, or an unsafe operation has been
used while violating the preconditions.

instanceName :: c -> String Source #

The name of the module implementing `c`

class (CollX c a, Ord a) => OrdCollX c a | c -> a where Source #

Collections for which the elements have an ordering relation.

deleteMin, deleteMax, unsafeInsertMin, unsafeInsertMax, unsafeFromOrdSeq, unsafeAppend, filterLT, filterLE, filterGT, filterGE, partitionLT_GE, partitionLE_GT, partitionLT_GT

Delete the minimum element from the collection. If there is more than one minimum, it is unspecified which is deleted. If the collection is empty, it will be returned unchanged.

This function is *ambiguous* at bag types if more than one minimum
element exists in the bag. Otherwise it is *unambiguous*.

Delete the maximum element from the collection. If there is more than one maximum, it is unspecified which is deleted. If the collection is empty, it will be returned unchanged.

This function is *ambiguous* at bag types if more than one maximum
element exists in the bag. Otherwise it is *unambiguous*.

unsafeInsertMin :: a -> c -> c Source #

Insert an element into a collection which is guaranteed to be
`<=`

any existing elements in the collection. For sets, the
precondition is strengthened to `<`

.

This function is *unambiguous*, under the above preconditions.

unsafeInsertMax :: a -> c -> c Source #

Insert an element into a collection which is guaranteed to be
`>=`

any existing elements in the collection. For sets, the
precondition is strengthened to `>`

.

This function is *unambiguous*, under the above preconditions.

unsafeFromOrdSeq :: Sequence seq => seq a -> c Source #

Convert a sequence in non-decreasing order into a collection. For sets, the sequence must be in increasing order.

This function is *unambiguous*, under the above preconditions.

unsafeAppend :: c -> c -> c Source #

Union two collections where every element in the first
collection is `<=`

every element in the second collection.
For sets, this precondition is strengthened to `<`

.

This function is *unambiguous*, under the above preconditions.

filterLT :: a -> c -> c Source #

Extract the sub-collection of elements `<`

the given element.

*Axioms:*

filterLT x xs = filter (< x) xs

This function is always *unambiguous*.

filterLE :: a -> c -> c Source #

Extract the sub-collection of elements `<=`

the given element.

*Axioms:*

filterLE x xs = filter (<= x) xs

This function is always *unambiguous*.

filterGT :: a -> c -> c Source #

Extract the sub-collection of elements `>`

the given element.

*Axioms:*

filterGT x xs = filter (> x) xs

This function is always *unambiguous*.

filterGE :: a -> c -> c Source #

Extract the sub-collection of elements `>=`

the given element.

*Axioms:*

filterGE x xs = filter (>= x) xs

This function is always *unambiguous*.

partitionLT_GE :: a -> c -> (c, c) Source #

Split a collection into those elements `<`

a given element and
those `>=`

.

*Axioms:*

partitionLT_GE xs = partition (<) xs

This function is always *unambiguous*.

partitionLE_GT :: a -> c -> (c, c) Source #

Split a collection into those elements `<=`

a given element and
those `>`

.

*Axioms:*

partitionLE_GT xs = partition (<=) xs

This function is always *unambiguous*.

partitionLT_GT :: a -> c -> (c, c) Source #

Split a collection into those elements `<`

a given element and
those `>`

. All elements equal to the given element are discarded.

*Axioms:*

partitionLT_GT x xs = (filterLT x xs,filterGT x xs)

This function is always *unambiguous*.

class CollX c a => SetX c a | c -> a where Source #

A collection where the set property is maintained; that is, a set
contains at most one element of the equivalence class formed by the
`Eq`

instance on the elements.

intersection :: c -> c -> c Source #

Computes the intersection of two sets. It is unspecified which element is kept when equal elements appear in each set.

This function is *ambiguous*, except when the sets are disjoint.

difference :: c -> c -> c Source #

Computes the difference of two sets; that is, all elements in the first set which are not in the second set.

This function is always *unambiguous*.

symmetricDifference :: c -> c -> c Source #

Computes the symmetric difference of two sets; that is, all elements which appear in exactily one of the two sets.

This function is always *unambiguous*.

properSubset :: c -> c -> Bool Source #

Test whether the first set is a proper subset of the second set; that is, if every element in the first set is also a member of the second set AND there exists some element in the second set which is not present in the first.

This function is always *unambiguous*.

subset :: c -> c -> Bool Source #

Test whether the first set is a subset of the second set; that is, if every element in the first set is also a member of the second set.

This function is always *unambiguous*.

class (OrdCollX c a, SetX c a) => OrdSetX c a | c -> a Source #

Sets where the elements also have an ordering relation.
This class contains no methods; it is only an abbreviation for
the context `(OrdCollX c a,SetX c a)`

.

# Observable collections

class CollX c a => Coll c a | c -> a where Source #

Collections with observable elements. See the module documentation for comments on observability.

toSeq, lookup, lookupM, lookupAll, lookupWithDefault, fold, fold', fold1, fold1', filter, partition, strictWith

toSeq :: Sequence seq => c -> seq a Source #

List the elements of the collection in an unspecified order.

This function is *ambiguous* iff the collection contains more
than one element.

lookup :: a -> c -> a Source #

Lookup one element equal to the given element. If no elements exist in the collection equal to the given element, an error is signaled. If multiple copies of the given element exist in the collection, it is unspecified which is returned.

This function is *ambiguous* at bag types, when more than one
element equivalent to the given item is in the bag. Otherwise
it is *unambiguous*.

lookupM :: Monad m => a -> c -> m a Source #

Lookup one element equal to the given element. If no elements
exist in the collection equal to the given element, `fail`

is called.
If multiple copies of the given element exist in the collection, it
is unspecified which is returned.

This function is *ambiguous* at bag types, when more than one
element equivalent to the given item is in the bag. Otherwise
it is *unambiguous*.

lookupAll :: Sequence seq => a -> c -> seq a Source #

Return a sequence containing all elements in the collection equal to the given element in an unspecified order.

This function is *ambiguous* at bag types, when more than one
element equivalent to the given item is in the bag. Otherwise
it is *unambiguous*.

lookupWithDefault :: a -> a -> c -> a Source #

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.

*ambiguous* at bag types, when more than one
element equivalent to the given item is in the bag. Otherwise
it is *unambiguous*.

fold :: (a -> b -> b) -> b -> c -> b Source #

Fold over all the elements in a collection in an unspecified order.

`fold f`

is *unambiguous* iff `f`

is fold-commutative.

fold' :: (a -> b -> b) -> b -> c -> b Source #

A strict variant of `fold`

.

`fold' f`

is *unambiguous* iff `f`

is fold-commutative.

fold1 :: (a -> a -> a) -> c -> a Source #

Fold over all the elements in a collection in an unspecified order. An error is signaled if the collection is empty.

`fold1 f`

is *unambiguous* iff `f`

is fold-commutative.

fold1' :: (a -> a -> a) -> c -> a Source #

A strict variant of `fold1`

.

`fold1' f`

is *unambiguous* iff `f`

is fold-commutative.

filter :: (a -> Bool) -> c -> c Source #

Remove all elements not satisfying the predicate.

This function is always *unambiguous*.

partition :: (a -> Bool) -> c -> (c, c) Source #

Returns two collections, the first containing all the elements satisfying the predicate, and the second containing all the elements not satisfying the predicate.

This function is always *unambiguous*.

strictWith :: (a -> b) -> c -> c Source #

Similar to `strict`

, this function walks the datastructure forcing closures.
However, `strictWith`

will additionally apply the given function to the
collection elements, force the result using `seq`

, and then ignore it.
This function can be used to perform various levels of forcing on the
sequence elements. In particular:

strictWith id xs

will force the spine of the datastructure and reduce each element to WHNF.

This function is always *unambiguous*.

class (Coll c a, OrdCollX c a) => OrdColl c a | c -> a where Source #

Collections with observable elements where the elements additionally have an ordering relation. See the module documentation for comments on observability.

minView, minElem, maxView, maxElem, foldr, foldr', foldl, foldl', foldr1, foldr1', foldl1, foldl1', toOrdSeq, unsafeMapMonotonic

minView :: Monad m => c -> m (a, c) Source #

Return the minimum element in the collection, together with
the collection without that element. If there are multiple
copies of the minimum element, it is unspecified which is chosen.
*Note* that `minView`

, `minElem`

, and `deleteMin`

may make different
choices. Calls `fail`

if the collection is empty.

This function is *ambiguous* at bag types, if more than one minimum
element exists in the bag. Otherwise, it is *unambiguous*.

Return the minimum element in the collection. If there are multiple
copies of the minimum element, it is unspecified which is chosen.
*Note* that `minView`

, `minElem`

, and `deleteMin`

may make different
choices. Signals an error if the collection is empty.

This function is *ambiguous* at bag types, if more than one minimum
element exists in the bag. Otherwise, it is *unambiguous*.

maxView :: Monad m => c -> m (a, c) Source #

Return the maximum element in the collection, together with
the collection without that element. If there are multiple
copies of the maximum element, it is unspecified which is chosen.
*Note* that `maxView`

, `maxElem`

and `deleteMax`

may make different
choices. Calls `fail`

if the collection is empty.

This function is *ambiguous* at bag types, if more than one maximum
element exists in the bag. Otherwise, it is *unambiguous*.

Return the maximum element in the collection. If there are multiple
copies of the maximum element, it is unspecified which is chosen.
*Note* that `maxView`

, `maxElem`

and `deleteMax`

may make different
choices. Signals an error if the collection is empty.

This function is *ambiguous* at bag types, if more than one maximum
element exists in the bag. Otherwise, it is *unambiguous*.

foldr :: (a -> b -> b) -> b -> c -> b Source #

Fold across the elements in non-decreasing order with right associativity. (For sets, this will always be increasing order)

This function is *unambiguous* if the combining function is
fold-commutative, at all set types, and at bag types
where no two equivalent elements exist in the bag. Otherwise
it is *ambiguous*.

foldr' :: (a -> b -> b) -> b -> c -> b Source #

A strict variant of `foldr`

.

This function is *unambiguous* if the combining function is
fold-commutative, at all set types, and at bag types
where no two equivalent elements exist in the bag. Otherwise
it is *ambiguous*.

foldl :: (b -> a -> b) -> b -> c -> b Source #

Fold across the elements in non-decreasing order with left associativity. (For sets, this will always be increasing order)

This function is *unambiguous* if the combining function is
fold-commutative, at all set types, and at bag types
where no two equivalent elements exist in the bag. Otherwise
it is *ambiguous*.

foldl' :: (b -> a -> b) -> b -> c -> b Source #

A strict variant of `foldl`

.

*unambiguous* if the combining function is
fold-commutative, at all set types, and at bag types
where no two equivalent elements exist in the bag. Otherwise
it is *ambiguous*.

foldr1 :: (a -> a -> a) -> c -> a Source #

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)

*unambiguous* if the combining function is
fold-commutative, at all set types, and at bag types
where no two equivalent elements exist in the bag. Otherwise
it is *ambiguous*.

foldr1' :: (a -> a -> a) -> c -> a Source #

A strict variant of `foldr1`

.

*unambiguous* if the combining function is
fold-commutative, at all set types, and at bag types
where no two equivalent elements exist in the bag. Otherwise
it is *ambiguous*.

foldl1 :: (a -> a -> a) -> c -> a Source #

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)

*unambiguous* if the combining function is
fold-commutative, at all set types, and at bag types
where no two equivalent elements exist in the bag. Otherwise
it is *ambiguous*.

foldl1' :: (a -> a -> a) -> c -> a Source #

A strict variant of `foldl1`

.

*unambiguous* if the combining function is
fold-commutative, at all set types, and at bag types
where no two equivalent elements exist in the bag. Otherwise
it is *ambiguous*.

toOrdSeq :: Sequence seq => c -> seq a Source #

List the elements in non-decreasing order. (For sets, this will always be increasing order)

At set types, this function is *unambiguous*. At bag types, it
is *unambiguous* if no two equivalent elements exist in the bag;
otherwise it is *ambiguous*.

unsafeMapMonotonic :: (a -> a) -> c -> c Source #

Map a monotonic function across all elements of a collection. The function is required to satisfy the following precondition:

forall x y. x < y ==> f x < f y

This function is *unambiguous*, under the precondition.

class (Coll c a, SetX c a) => Set c a | c -> a where Source #

Collections with observable elements where the set property is maintained;
that is, a set contains at most one element of the equivalence class
formed by the `Eq`

instance on the elements.

*WARNING: Each of the following "With" functions is unsafe.*
The passed in combining functions are used to choose which element is kept
in the case of duplicates. They are required to satisfy the precondition
that, given two equal elements, they return a third element equal to the
other two. Usually, the combining function just returns its first or
second argument, but it can combine elements in non-trivial ways.

The combining function should usually be associative. Where the function involves a sequence of elements, the elements will be combined from left-to-right, but with an unspecified associativity.

For example, if `x == y == z`

,
then `fromSeqWith (+) [x,y,z]`

equals either
`single (x + (y + z))`

or
`single ((x + y) + z)`

fromSeqWith :: Sequence seq => (a -> a -> a) -> seq a -> c Source #

Same as `fromSeq`

but with a combining function to resolve duplicates.

This function is *unambiguous* under the "with" precondition
if the combining function is associative. Otherwise it is *ambiguous*.

insertWith :: (a -> a -> a) -> a -> c -> c Source #

Same as `insert`

but with a combining function to resolve duplicates.

This function is *unambiguous* under the "with" precondition.

insertSeqWith :: Sequence seq => (a -> a -> a) -> seq a -> c -> c Source #

Same as `insertSeq`

but with a combining function to resolve duplicates.

This function is *unambiguous* under the "with" precondition
if the combining function is associative. Otherwise it is *ambiguous*.

unionl :: c -> c -> c Source #

Left biased union.

*Axioms:*

unionl = unionWith (\x y -> x)

This function is always *unambiguous*.

unionr :: c -> c -> c Source #

Right biased union.

*Axioms:*

unionr = unionWith (\x y -> y)

This function is always *unambiguous*.

unionWith :: (a -> a -> a) -> c -> c -> c Source #

Same as `union`

, but with a combining function to resolve duplicates.

This function is *unambiguous* under the "with" precondition.

unionSeqWith :: Sequence seq => (a -> a -> a) -> seq c -> c Source #

Same as `unionSeq`

, but with a combining function to resolve duplicates.

This function is *unambiguous* under the "with" precondition
if the combining function is associative. Otherwise it is *ambiguous*.

intersectionWith :: (a -> a -> a) -> c -> c -> c Source #

Same as `intersection`

, but with a combining function to resolve duplicates.

This function is *unambiguous* under the "with" precondition.

class (OrdColl c a, Set c a) => OrdSet c a | c -> a Source #

Collections with observable elements where the set property is maintained and where additionally, there is an ordering relation on the elements. This class introduces no new methods, and is simply an abbreviation for the context:

(OrdColl c a,Set c a)

# Specializations of all the sequence operations to lists

insertList :: CollX c a => [a] -> c -> c Source #

deleteList :: CollX c a => [a] -> c -> c Source #

unsafeFromOrdList :: OrdCollX c a => [a] -> c Source #

lookupList :: Coll c a => a -> c -> [a] Source #

fromListWith :: Set c a => (a -> a -> a) -> [a] -> c Source #

insertListWith :: Set c a => (a -> a -> a) -> [a] -> c -> c Source #

unionListWith :: Set c a => (a -> a -> a) -> [c] -> c Source #