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


-- | A class for finite and recursively enumerable types and some helper functions for enumerating them
--   
--   A class for finite and recursively enumerable types and some helper
--   functions for enumerating them
@package universe-base
@version 1.0.2.1

module Data.Universe.Helpers

-- | For many types, the <tt>universe</tt> should be <tt>[minBound ..
--   maxBound]</tt>; <a>universeDef</a> makes it easy to make such types an
--   instance of <tt>Universe</tt> via the snippet
--   
--   <pre>
--   instance Universe Foo where universe = universeDef
--   </pre>
universeDef :: (Bounded a, Enum a) => [a]

-- | Fair n-way interleaving: given a finite number of (possibly infinite)
--   lists, produce a single list such that whenever <tt>v</tt> has finite
--   index in one of the input lists, <tt>v</tt> also has finite index in
--   the output list. No list's elements occur more frequently (on average)
--   than another's.
interleave :: [[a]] -> [a]

-- | Unfair n-way interleaving: given a possibly infinite number of
--   (possibly infinite) lists, produce a single list such that whenever
--   <tt>v</tt> has finite index in an input list at finite index,
--   <tt>v</tt> also has finite index in the output list. Elements from
--   lists at lower index occur more frequently, but not exponentially so.
diagonal :: [[a]] -> [a]

-- | Like <a>diagonal</a>, but expose a tiny bit more (non-semantic)
--   information: if you lay out the input list in two dimensions, each
--   list in the result will be one of the diagonals of the input. In
--   particular, each element of the output will be a list whose elements
--   are each from a distinct input list.
diagonals :: [[a]] -> [[a]]

-- | Fair 2-way interleaving.
(+++) :: [a] -> [a] -> [a]

-- | Slightly unfair 2-way Cartesian product: given two (possibly infinite)
--   lists, produce a single list such that whenever <tt>v</tt> and
--   <tt>w</tt> have finite indices in the input lists, <tt>(v,w)</tt> has
--   finite index in the output list. Lower indices occur as the
--   <tt>fst</tt> part of the tuple more frequently, but not exponentially
--   so.
(+*+) :: [a] -> [b] -> [(a, b)]

-- | Slightly unfair n-way Cartesian product: given a finite number of
--   (possibly infinite) lists, produce a single list such that whenever
--   <tt>vi</tt> has finite index in list i for each i, <tt>[v1, ...,
--   vn]</tt> has finite index in the output list.
choices :: [[a]] -> [[a]]

-- | Very unfair 2-way Cartesian product: same guarantee as the slightly
--   unfair one, except that lower indices may occur as the <tt>fst</tt>
--   part of the tuple exponentially more frequently. This mainly exists as
--   a specification to test against.
unfairCartesianProduct :: [a] -> [b] -> [(a, b)]

-- | Very unfair n-way Cartesian product: same guarantee as the slightly
--   unfair one, but not as good in the same sense that the very unfair
--   2-way product is worse than the slightly unfair 2-way product. Mainly
--   for testing purposes.
unfairChoices :: [[a]] -> [[a]]

module Data.Universe.Class

-- | Creating an instance of this class is a declaration that your type is
--   recursively enumerable (and that <a>universe</a> is that enumeration).
--   In particular, you promise that any finite inhabitant has a finite
--   index in <a>universe</a>, and that no inhabitant appears at two
--   different finite indices.
class Universe a where universe = universeDef
universe :: Universe a => [a]

-- | Creating an instance of this class is a declaration that your
--   <a>universe</a> eventually ends. Minimal definition: no methods
--   defined. By default, <tt>universeF = universe</tt>, but for some types
--   (like <a>Either</a>) the <a>universeF</a> method may have a more
--   intuitive ordering.
class Universe a => Finite a where universeF = universe
universeF :: Finite a => [a]
