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


-- | A library for permutations and combinations.
--   
--   This library includes data types for storing permutations and
--   combinations. It implements pure and impure types, the latter of which
--   can be modified in-place. The library uses aggressive inlining and
--   MutableByteArray#s internally, so it is very efficient.
--   
--   The main utility of the library is converting between the linear
--   representation of a permutation and a sequence of swaps. This allows,
--   for instance, applying a permutation or its inverse to an array with
--   O(1) memory use.
--   
--   Much of the interface for the library is based on the permutation and
--   combination functions in the GNU Scientific Library (GSL).
@package permutation
@version 0.5.0.5


-- | An overloaded interface to mutable permutations. For permutation types
--   which can be used with this interface, see <a>Data.Permute.IO</a> and
--   <a>Data.Permute.ST</a>.
module Data.Permute.MPermute

-- | Class for representing a mutable permutation. The type is
--   parameterized over the type of the monad, <tt>m</tt>, in which the
--   mutable permutation will be manipulated.
class (Monad m) => MPermute p m | p -> m, m -> p

-- | Get the size of a permutation.
getSize :: MPermute p m => p -> m Int

-- | Create a new permutation initialized to be the identity.
newPermute :: MPermute p m => Int -> m p

-- | Allocate a new permutation but do not initialize it.
newPermute_ :: MPermute p m => Int -> m p
unsafeGetElem :: MPermute p m => p -> Int -> m Int
unsafeSetElem :: MPermute p m => p -> Int -> Int -> m ()
unsafeSwapElems :: MPermute p m => p -> Int -> Int -> m ()

-- | Get a lazy list of the permutation elements. The laziness makes this
--   function slightly dangerous if you are modifying the permutation.
getElems :: MPermute p m => p -> m [Int]

-- | Set all the values of a permutation from a list of elements.
setElems :: MPermute p m => p -> [Int] -> m ()
unsafeFreeze :: MPermute p m => p -> m Permute
unsafeThaw :: MPermute p m => Permute -> m p

-- | Create a new permutation initialized to be the identity.
newPermute :: MPermute p m => Int -> m p

-- | Allocate a new permutation but do not initialize it.
newPermute_ :: MPermute p m => Int -> m p

-- | Construct a permutation from a list of elements. <tt>newListPermute n
--   is</tt> creates a permutation of size <tt>n</tt> with the <tt>i</tt>th
--   element equal to <tt>is !! i</tt>. For the permutation to be valid,
--   the list <tt>is</tt> must have length <tt>n</tt> and contain the
--   indices <tt>0..(n-1)</tt> exactly once each.
newListPermute :: (MPermute p m) => Int -> [Int] -> m p

-- | Construct a permutation from a list of swaps. <tt>newSwapsPermute n
--   ss</tt> creates a permutation of size <tt>n</tt> given a sequence of
--   swaps. If <tt>ss</tt> is <tt>[(i0,j0), (i1,j1), ..., (ik,jk)]</tt>,
--   the sequence of swaps is <tt>i0 &lt;-&gt; j0</tt>, then <tt>i1
--   &lt;-&gt; j1</tt>, and so on until <tt>ik &lt;-&gt; jk</tt>.
newSwapsPermute :: (MPermute p m) => Int -> [(Int, Int)] -> m p

-- | Construct a permutation from a list of disjoint cycles.
--   <tt>newCyclesPermute n cs</tt> creates a permutation of size
--   <tt>n</tt> which is the composition of the cycles <tt>cs</tt>.
newCyclesPermute :: (MPermute p m) => Int -> [[Int]] -> m p

-- | Construct a new permutation by copying another.
newCopyPermute :: (MPermute p m) => p -> m p

-- | <tt>copyPermute dst src</tt> copies the elements of the permutation
--   <tt>src</tt> into the permutation <tt>dst</tt>. The two permutations
--   must have the same size.
copyPermute :: (MPermute p m) => p -> p -> m ()

-- | Set a permutation to the identity.
setIdentity :: (MPermute p m) => p -> m ()

-- | <tt>getElem p i</tt> gets the value of the <tt>i</tt>th element of the
--   permutation <tt>p</tt>. The index <tt>i</tt> must be in the range
--   <tt>0..(n-1)</tt>, where <tt>n</tt> is the size of the permutation.
getElem :: (MPermute p m) => p -> Int -> m Int

-- | <tt>setElem p i x</tt> sets the value of the <tt>i</tt>th element of
--   the permutation <tt>p</tt>. The index <tt>i</tt> must be in the range
--   <tt>0..(n-1)</tt>, where <tt>n</tt> is the size of the permutation.
setElem :: (MPermute p m) => p -> Int -> Int -> m ()

-- | <tt>getIndexOf p x</tt> returns <tt>i</tt> sutch that <tt>getElem p
--   i</tt> equals <tt>x</tt>. This is a linear-time operation.
getIndexOf :: (MPermute p m) => p -> Int -> m Int

-- | <tt>swapElems p i j</tt> exchanges the <tt>i</tt>th and <tt>j</tt>th
--   elements of the permutation <tt>p</tt>.
swapElems :: (MPermute p m) => p -> Int -> Int -> m ()

-- | Get the size of a permutation.
getSize :: MPermute p m => p -> m Int

-- | Get a lazy list of the permutation elements. The laziness makes this
--   function slightly dangerous if you are modifying the permutation.
getElems :: MPermute p m => p -> m [Int]

-- | Set all the values of a permutation from a list of elements.
setElems :: MPermute p m => p -> [Int] -> m ()

-- | Returns whether or not the permutation is valid. For it to be valid,
--   the numbers <tt>0,...,(n-1)</tt> must all appear exactly once in the
--   stored values <tt>p[0],...,p[n-1]</tt>.
isValid :: (MPermute p m) => p -> m Bool

-- | Whether or not the permutation is made from an even number of swaps
getIsEven :: (MPermute p m) => p -> m Bool

-- | <tt>getPeriod p</tt> - The first power of <tt>p</tt> that is the
--   identity permutation
getPeriod :: (MPermute p m) => p -> m Integer

-- | Compute the inverse of a permutation.
getInverse :: (MPermute p m) => p -> m p

-- | Set one permutation to be the inverse of another. <tt>copyInverse inv
--   p</tt> computes the inverse of <tt>p</tt> and stores it in
--   <tt>inv</tt>. The two permutations must have the same size.
copyInverse :: (MPermute p m) => p -> p -> m ()

-- | Advance a permutation to the next permutation in lexicogrphic order
--   and return <tt>True</tt>. If no further permutaitons are available,
--   return <tt>False</tt> and leave the permutation unmodified. Starting
--   with the idendity permutation and repeatedly calling <tt>setNext</tt>
--   will iterate through all permutations of a given size.
setNext :: (MPermute p m) => p -> m Bool

-- | Step backwards to the previous permutation in lexicographic order and
--   return <tt>True</tt>. If there is no previous permutation, return
--   <tt>False</tt> and leave the permutation unmodified.
setPrev :: (MPermute p m) => p -> m Bool

-- | Get a lazy list of swaps equivalent to the permutation. A result of
--   <tt>[ (i0,j0), (i1,j1), ..., (ik,jk) ]</tt> means swap <tt>i0
--   &lt;-&gt; j0</tt>, then <tt>i1 &lt;-&gt; j1</tt>, and so on until
--   <tt>ik &lt;-&gt; jk</tt>. The laziness makes this function slightly
--   dangerous if you are modifying the permutation.
getSwaps :: (MPermute p m) => p -> m [(Int, Int)]

-- | Get a lazy list of swaps equivalent to the inverse of a permutation.
getInvSwaps :: (MPermute p m) => p -> m [(Int, Int)]

-- | <tt>getCycleFrom p i</tt> gets the list of elements reachable from
--   <tt>i</tt> by repeated application of <tt>p</tt>.
getCycleFrom :: (MPermute p m) => p -> Int -> m [Int]

-- | <tt>getCycles p</tt> returns the list of disjoin cycles in <tt>p</tt>.
getCycles :: (MPermute p m) => p -> m [[Int]]

-- | <tt>getSort n xs</tt> sorts the first <tt>n</tt> elements of
--   <tt>xs</tt> and returns a permutation which transforms <tt>xs</tt>
--   into sorted order. The results are undefined if <tt>n</tt> is greater
--   than the length of <tt>xs</tt>. This is a special case of
--   <a>getSortBy</a>.
getSort :: (Ord a, MPermute p m) => Int -> [a] -> m ([a], p)
getSortBy :: (MPermute p m) => (a -> a -> Ordering) -> Int -> [a] -> m ([a], p)

-- | <tt>getOrder n xs</tt> returns a permutation which rearranges the
--   first <tt>n</tt> elements of <tt>xs</tt> into ascending order. The
--   results are undefined if <tt>n</tt> is greater than the length of
--   <tt>xs</tt>. This is a special case of <a>getOrderBy</a>.
getOrder :: (Ord a, MPermute p m) => Int -> [a] -> m p
getOrderBy :: (MPermute p m) => (a -> a -> Ordering) -> Int -> [a] -> m p

-- | <tt>getRank n xs</tt> eturns a permutation, the inverse of which
--   rearranges the first <tt>n</tt> elements of <tt>xs</tt> into ascending
--   order. The returned permutation, <tt>p</tt>, has the property that
--   <tt>p[i]</tt> is the rank of the <tt>i</tt>th element of <tt>xs</tt>.
--   The results are undefined if <tt>n</tt> is greater than the length of
--   <tt>xs</tt>. This is a special case of <a>getRankBy</a>.
getRank :: (Ord a, MPermute p m) => Int -> [a] -> m p
getRankBy :: (MPermute p m) => (a -> a -> Ordering) -> Int -> [a] -> m p

-- | Convert a mutable permutation to an immutable one.
freeze :: (MPermute p m) => p -> m Permute
unsafeFreeze :: MPermute p m => p -> m Permute

-- | Convert an immutable permutation to a mutable one.
thaw :: (MPermute p m) => Permute -> m p
unsafeThaw :: MPermute p m => Permute -> m p
unsafeNewListPermute :: (MPermute p m) => Int -> [Int] -> m p
unsafeNewSwapsPermute :: (MPermute p m) => Int -> [(Int, Int)] -> m p
unsafeNewCyclesPermute :: (MPermute p m) => Int -> [[Int]] -> m p
unsafeGetElem :: MPermute p m => p -> Int -> m Int
unsafeSetElem :: MPermute p m => p -> Int -> Int -> m ()
unsafeSwapElems :: MPermute p m => p -> Int -> Int -> m ()
instance Data.Permute.MPermute.MPermute (Data.Permute.Base.STPermute s) (GHC.ST.ST s)
instance Data.Permute.MPermute.MPermute Data.Permute.IOBase.IOPermute GHC.Types.IO


-- | Mutable permutations in the <a>IO</a> monad.
module Data.Permute.IO

-- | A mutable permutation that can be manipulated in the <a>IO</a> monad.
data IOPermute


-- | Mutable permutations in the <a>ST</a> monad.
module Data.Permute.ST

-- | A mutable permutation that can be manipulated in the <a>ST</a> monad.
--   The type argument <tt>s</tt> is the state variable argument for the
--   <a>ST</a> type.
data STPermute s

-- | A safe way to create and work with a mutable permutation before
--   returning an immutable one for later perusal. This function avoids
--   copying the permutation before returning it - it uses unsafeFreeze
--   internally, but this wrapper is a safe interface to that function.
runSTPermute :: (forall s. ST s (STPermute s)) -> Permute


-- | Immutable permutations.
module Data.Permute

-- | The immutable permutation data type. Internally, a permutation of size
--   <tt>n</tt> is stored as an <tt>0</tt>-based array of <tt>n</tt>
--   <a>Int</a>s. The permutation represents a reordering of the integers
--   <tt>0, ..., (n-1)</tt>. The permutation sents the value p[i] to
--   <tt>i</tt>.
data Permute

-- | Construct an identity permutation of the given size.
permute :: Int -> Permute

-- | Construct a permutation from a list of elements. <tt>listPermute n
--   is</tt> creates a permutation of size <tt>n</tt> with the <tt>i</tt>th
--   element equal to <tt>is !! i</tt>. For the permutation to be valid,
--   the list <tt>is</tt> must have length <tt>n</tt> and contain the
--   indices <tt>0..(n-1)</tt> exactly once each.
listPermute :: Int -> [Int] -> Permute

-- | Construct a permutation from a list of swaps. <tt>swapsPermute n
--   ss</tt> creats a permutation of size <tt>n</tt> given by a sequence of
--   swaps. If <tt>ss</tt> is <tt>[(i0,j0), (i1,j1), ..., (ik,jk)]</tt>,
--   the sequence of swaps is <tt>i0 &lt;-&gt; j0</tt>, then <tt>i1
--   &lt;-&gt; j1</tt>, and so on until <tt>ik &lt;-&gt; jk</tt>.
swapsPermute :: Int -> [(Int, Int)] -> Permute

-- | Construct a permutation from a list of disjoint cycles.
--   <tt>cyclesPermute n cs</tt> creates a permutation of size <tt>n</tt>
--   which is the composition of the cycles <tt>cs</tt>.
cyclesPermute :: Int -> [[Int]] -> Permute

-- | <tt>at p i</tt> gets the value of the <tt>i</tt>th element of the
--   permutation <tt>p</tt>. The index <tt>i</tt> must be in the range
--   <tt>0..(n-1)</tt>, where <tt>n</tt> is the size of the permutation.
at :: Permute -> Int -> Int
unsafeAt :: Permute -> Int -> Int

-- | <tt>indexOf p x</tt> gets an index <tt>i</tt> such that <tt>at p
--   i</tt> equals <tt>x</tt>.
indexOf :: Permute -> Int -> Int

-- | Get the size of the permutation.
size :: Permute -> Int

-- | Get a list of the permutation elements.
elems :: Permute -> [Int]

-- | Whether or not the permutation is made from an even number of swaps
isEven :: Permute -> Bool

-- | <tt>period p</tt> - The first power of <tt>p</tt> that is the identity
--   permutation
period :: Permute -> Integer

-- | Get the inverse of a permutation.
inverse :: Permute -> Permute

-- | Return the next permutation in lexicographic order, or
--   <tt>Nothing</tt> if there are no further permutations. Starting with
--   the identity permutation and repeatedly calling this function will
--   iterate through all permutations of a given order.
next :: Permute -> Maybe Permute

-- | Return the previous permutation in lexicographic order, or
--   <tt>Nothing</tt> if no such permutation exists.
prev :: Permute -> Maybe Permute

-- | Get a list of swaps equivalent to the permutation. A result of <tt>[
--   (i0,j0), (i1,j1), ..., (ik,jk) ]</tt> means swap <tt>i0 &lt;-&gt;
--   j0</tt>, then <tt>i1 &lt;-&gt; j1</tt>, and so on until <tt>ik
--   &lt;-&gt; jk</tt>.
swaps :: Permute -> [(Int, Int)]

-- | Get a list of swaps equivalent to the inverse of permutation.
invSwaps :: Permute -> [(Int, Int)]

-- | <tt>cycleFrom p i</tt> gets the list of elements reachable from
--   <tt>i</tt> by repeated application of <tt>p</tt>.
cycleFrom :: Permute -> Int -> [Int]

-- | <tt>cycles p</tt> returns the list of disjoin cycles in <tt>p</tt>.
cycles :: Permute -> [[Int]]

-- | <tt>sort n xs</tt> sorts the first <tt>n</tt> elements of <tt>xs</tt>
--   and returns a permutation which transforms <tt>xs</tt> into sorted
--   order. The results are undefined if <tt>n</tt> is greater than the
--   length of <tt>xs</tt>. This is a special case of <a>sortBy</a>.
sort :: (Ord a) => Int -> [a] -> ([a], Permute)
sortBy :: (a -> a -> Ordering) -> Int -> [a] -> ([a], Permute)

-- | <tt>order n xs</tt> returns a permutation which rearranges the first
--   <tt>n</tt> elements of <tt>xs</tt> into ascending order. The results
--   are undefined if <tt>n</tt> is greater than the length of <tt>xs</tt>.
--   This is a special case of <a>orderBy</a>.
order :: (Ord a) => Int -> [a] -> Permute
orderBy :: (a -> a -> Ordering) -> Int -> [a] -> Permute

-- | <tt>rank n xs</tt> eturns a permutation, the inverse of which
--   rearranges the first <tt>n</tt> elements of <tt>xs</tt> into ascending
--   order. The returned permutation, <tt>p</tt>, has the property that
--   <tt>p[i]</tt> is the rank of the <tt>i</tt>th element of <tt>xs</tt>.
--   The results are undefined if <tt>n</tt> is greater than the length of
--   <tt>xs</tt>. This is a special case of <a>rankBy</a>.
rank :: (Ord a) => Int -> [a] -> Permute
rankBy :: (a -> a -> Ordering) -> Int -> [a] -> Permute


-- | An overloaded interface to mutable combinations. For combination types
--   which can be used with this interface, see <a>Data.Choose.IO</a> and
--   <a>Data.Choose.ST</a>.
module Data.Choose.MChoose

-- | Class for representing a mutable combination. The type is
--   parameterized over the type of the monad, <tt>m</tt>, in which the
--   mutable combination will be manipulated.
class (Monad m) => MChoose c m | c -> m, m -> c

-- | Get the number of possibilities, <tt>n</tt> in the combination.
getPossible :: MChoose c m => c -> m Int

-- | Get the number of outcomes, <tt>k</tt> in the combination.
getSize :: MChoose c m => c -> m Int

-- | <tt>newChoose n k</tt> creates a new combination of <tt>k</tt>
--   outcomes from <tt>n</tt> possibilites initialized to the subset <tt>{
--   0, ..., k-1 }</tt>.
newChoose :: MChoose c m => Int -> Int -> m c

-- | <tt>newChoose n k</tt> allocates a new combination of <tt>k</tt>
--   outcomes from <tt>n</tt> possibilities but does not initialize it.
newChoose_ :: MChoose c m => Int -> Int -> m c
unsafeGetElem :: MChoose c m => c -> Int -> m Int
unsafeSetElem :: MChoose c m => c -> Int -> Int -> m ()

-- | Get a lazy list of the combination elements. The laziness makes this
--   function slightly dangerous if you are modifying the combination.
getElems :: MChoose c m => c -> m [Int]

-- | Set all the values of a combination from a list of elements.
setElems :: MChoose c m => c -> [Int] -> m ()
unsafeFreeze :: MChoose c m => c -> m Choose
unsafeThaw :: MChoose c m => Choose -> m c

-- | <tt>newChoose n k</tt> creates a new combination of <tt>k</tt>
--   outcomes from <tt>n</tt> possibilites initialized to the subset <tt>{
--   0, ..., k-1 }</tt>.
newChoose :: MChoose c m => Int -> Int -> m c

-- | <tt>newChoose n k</tt> allocates a new combination of <tt>k</tt>
--   outcomes from <tt>n</tt> possibilities but does not initialize it.
newChoose_ :: MChoose c m => Int -> Int -> m c

-- | Construct a combination from a list of elements. <tt>newListChoose n k
--   is</tt> creates a combination of <tt>k</tt> outcomes from <tt>n</tt>
--   possibilities initialized to have the <tt>i</tt>th element equal to
--   <tt>is !! i</tt>. For the combination to be valid, the elements must
--   all be unique, they must be in sorted order, and they all must be in
--   the range <tt>0 .. n-1</tt>.
newListChoose :: (MChoose c m) => Int -> Int -> [Int] -> m c

-- | Construct a new combination by copying another.
newCopyChoose :: (MChoose c m) => c -> m c

-- | <tt>copyChoose dst src</tt> copies the elements of the combination
--   <tt>src</tt> into the combination <tt>dst</tt>. The two combinations
--   must have the same size.
copyChoose :: (MChoose c m) => c -> c -> m ()

-- | Set a combination to be the first subset of its size.
setFirst :: (MChoose c m) => c -> m ()

-- | <tt>getElem c i</tt> gets the value of the <tt>i</tt>th element of the
--   combination <tt>c</tt>. The index <tt>i</tt> must be in the range
--   <tt>0..k-1</tt>, where <tt>n</tt> is the size of the combination.
getElem :: (MChoose c m) => c -> Int -> m Int

-- | <tt>setElem c i x</tt> sets the value of the <tt>i</tt>th element of
--   the combination <tt>c</tt>. The index <tt>i</tt> must be in the range
--   <tt>0..k-1</tt>, where <tt>k</tt> is the size of the combination.
setElem :: (MChoose c m) => c -> Int -> Int -> m ()

-- | Get the number of possibilities, <tt>n</tt> in the combination.
getPossible :: MChoose c m => c -> m Int

-- | Get the number of outcomes, <tt>k</tt> in the combination.
getSize :: MChoose c m => c -> m Int

-- | Get a lazy list of the combination elements. The laziness makes this
--   function slightly dangerous if you are modifying the combination.
getElems :: MChoose c m => c -> m [Int]

-- | Set all the values of a combination from a list of elements.
setElems :: MChoose c m => c -> [Int] -> m ()

-- | Returns whether or not the combination is valid. For it to be valid,
--   the elements must all be unique, they must be in sorted order, and
--   they all must be in the range <tt>0 .. n-1</tt>, where <tt>n</tt> is
--   the number of possibilies in the combination.
isValid :: (MChoose c m) => c -> m Bool

-- | Compute the complement of a combination
getComplement :: (MChoose c m) => c -> m c

-- | Return a lazy list of the elements in the complement of a combination.
--   If the combination is a subset of <tt>k</tt> outcomes from <tt>n</tt>
--   possibilities, then the returned list will be sorted and of length
--   <tt>n-k</tt>. Due to the laziness, you should be careful when using
--   this function if you are also modifying the combination.
getComplElems :: (MChoose c m) => c -> m [Int]

-- | Advance a combination to the next in lexicogrphic order and return
--   <tt>True</tt>. If no further combinations are available, return
--   <tt>False</tt> and leave the combination unmodified. Starting with
--   <tt>[ 0 .. k-1 ]</tt> and repeatedly calling <tt>setNext</tt> will
--   iterate through all subsets of size <tt>k</tt>.
setNext :: (MChoose c m) => c -> m Bool

-- | Step backwards to the previous combination in lexicographic order and
--   return <tt>True</tt>. If there is no previous combination, return
--   <tt>False</tt> and leave the combination unmodified.
setPrev :: (MChoose c m) => c -> m Bool

-- | Convert a mutable combination to an immutable one.
freeze :: (MChoose c m) => c -> m Choose
unsafeFreeze :: MChoose c m => c -> m Choose

-- | Convert an immutable combination to a mutable one.
thaw :: (MChoose c m) => Choose -> m c
unsafeThaw :: MChoose c m => Choose -> m c
unsafeNewListChoose :: (MChoose c m) => Int -> Int -> [Int] -> m c
unsafeGetElem :: MChoose c m => c -> Int -> m Int
unsafeSetElem :: MChoose c m => c -> Int -> Int -> m ()
instance Data.Choose.MChoose.MChoose (Data.Choose.Base.STChoose s) (GHC.ST.ST s)
instance Data.Choose.MChoose.MChoose Data.Choose.IOBase.IOChoose GHC.Types.IO


-- | Mutable combinations in the <a>IO</a> monad.
module Data.Choose.IO

-- | A mutable combination that can be manipulated in the <a>IO</a> monad.
data IOChoose


-- | Mutable combinations in the <a>ST</a> monad.
module Data.Choose.ST

-- | A mutable combination that can be manipulated in the <a>ST</a> monad.
--   The type argument <tt>s</tt> is the state variable argument for the
--   <a>ST</a> type.
data STChoose s

-- | A safe way to create and work with a mutable combination before
--   returning an immutable one for later perusal. This function avoids
--   copying the combination before returning it - it uses unsafeFreeze
--   internally, but this wrapper is a safe interface to that function.
runSTChoose :: (forall s. ST s (STChoose s)) -> Choose


-- | Immutable combinations.
module Data.Choose

-- | The immutable combination data type. A way of representing <tt>k</tt>
--   unordered outcomes from <tt>n</tt> possiblities. The possibilites are
--   represented as the indices <tt>0, ..., n-1</tt>, and the outcomes are
--   given as a subset of size <tt>k</tt>. The subset is stored with the
--   indices in ascending order.
data Choose

-- | <tt>choose n k</tt> returns the first combination of <tt>k</tt>
--   outcomes from <tt>n</tt> possibilites, namely the subset <tt>{ 0, ...,
--   k-1 }</tt>.
choose :: Int -> Int -> Choose

-- | Construct a combination from a list of elements. <tt>listChoose n k
--   is</tt> creates a combination of <tt>k</tt> outcomes from <tt>n</tt>
--   possibilities initialized to have the <tt>i</tt>th element equal to
--   <tt>is !! i</tt>. For the combination to be valid, the elements must
--   all be unique, they must be in sorted order, and they all must be in
--   the range <tt>0 .. n-1</tt>.
listChoose :: Int -> Int -> [Int] -> Choose

-- | <tt>at c i</tt> gets the value of the <tt>i</tt>th element of the
--   combination <tt>c</tt>. The index <tt>i</tt> must be in the range
--   <tt>0..(k-1)</tt>, where <tt>k</tt> is the size of the combination.
at :: Choose -> Int -> Int
unsafeAt :: Choose -> Int -> Int

-- | Get the number of possibilities, <tt>n</tt>.
possible :: Choose -> Int

-- | Get the number of outcomes, <tt>k</tt>.
size :: Choose -> Int

-- | Get a list of the <tt>k</tt> outcomes.
elems :: Choose -> [Int]

-- | Get the inverse of a combination
complement :: Choose -> Choose

-- | Get a list of the elements in the complement of a combination. If the
--   combination is a subset of <tt>k</tt> outcomes from <tt>n</tt>
--   possibilities, then the returned list will be sorted and of length
--   <tt>n-k</tt>.
complElems :: Choose -> [Int]

-- | Return the next combination in lexicographic order, or
--   <tt>Nothing</tt> if there are no further combinations. Starting with
--   the first combination and repeatedly calling this function will
--   iterate through all combinations of a given order.
next :: Choose -> Maybe Choose

-- | Return the previous combination in lexicographic order, or
--   <tt>Nothing</tt> if such combination exists.
prev :: Choose -> Maybe Choose
