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


-- | Efficient relational queries on Haskell sets.
--   
--   This Haskell package provides a data structure of sets that are
--   indexed by potentially multiple indices.
--   
--   Sets can be created, modified, and queried in various ways.
--   
--   The package is a variant of the <a>ixset</a> package. The ixset
--   package makes use of run-time type information to find a suitable
--   index on a query, resulting in possible run-time errors when no
--   suitable index exists. In ixset-typed, the types of all indices
--   available or tracked in the type system. Thus, ixset-typed should be
--   safer to use than ixset, but in turn requires more GHC extensions.
--   
--   At the moment, the two packages are relatively compatible. As a
--   consequence of the more precise types, a few manual tweaks are
--   necessary when switching from one to the other, but the interface is
--   mostly the same.
@package ixset-typed
@version 0.3.1


-- | This module defines <tt>Typeable</tt> indexes and convenience
--   functions. Should probably be considered private to
--   <tt>Data.IxSet.Typed</tt>.
module Data.IxSet.Typed.Ix

-- | <a>Ix</a> is a <a>Map</a> from some key (of type <tt>ix</tt>) to a
--   <a>Set</a> of values (of type <tt>a</tt>) for that key.
data Ix (ix :: *) (a :: *)
[Ix] :: !(Map ix (Set a)) -> (a -> [ix]) -> Ix ix a

-- | Convenience function for inserting into <a>Map</a>s of <a>Set</a>s as
--   in the case of an <a>Ix</a>. If they key did not already exist in the
--   <a>Map</a>, then a new <a>Set</a> is added transparently.
insert :: (Ord a, Ord k) => k -> a -> Map k (Set a) -> Map k (Set a)

-- | Convenience function for deleting from <a>Map</a>s of <a>Set</a>s. If
--   the resulting <a>Set</a> is empty, then the entry is removed from the
--   <a>Map</a>.
delete :: (Ord a, Ord k) => k -> a -> Map k (Set a) -> Map k (Set a)

-- | Helper function to create a new index from a list.
fromList :: (Ord a, Ord k) => [(k, a)] -> Map k (Set a)

-- | Helper function to <a>insert</a> a list of elements into a set.
insertList :: (Ord a, Ord k) => [(k, a)] -> Map k (Set a) -> Map k (Set a)

-- | Helper function to <a>delete</a> a list of elements from a set.
deleteList :: (Ord a, Ord k) => [(k, a)] -> Map k (Set a) -> Map k (Set a)

-- | Takes the union of two sets.
union :: (Ord a, Ord k) => Map k (Set a) -> Map k (Set a) -> Map k (Set a)

-- | Takes the intersection of two sets.
intersection :: (Ord a, Ord k) => Map k (Set a) -> Map k (Set a) -> Map k (Set a)
instance (Control.DeepSeq.NFData ix, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Data.IxSet.Typed.Ix.Ix ix a)


-- | An efficient implementation of queryable sets.
--   
--   Assume you have a family of types such as:
--   
--   <pre>
--   data Entry      = Entry Author [Author] Updated Id Content
--     deriving (Show, Eq, Ord, Data, Typeable)
--   newtype Updated = Updated UTCTime
--     deriving (Show, Eq, Ord, Data, Typeable)
--   newtype Id      = Id Int64
--     deriving (Show, Eq, Ord, Data, Typeable)
--   newtype Content = Content String
--     deriving (Show, Eq, Ord, Data, Typeable)
--   newtype Author  = Author Email
--     deriving (Show, Eq, Ord, Data, Typeable)
--   type Email      = String
--   data Test = Test
--     deriving (Show, Eq, Ord, Data, Typeable)
--   </pre>
--   
--   <ol>
--   <li>Decide what parts of your type you want indexed and make your type
--   an instance of <a>Indexable</a>. Use <a>ixFun</a> and <a>ixGen</a> to
--   build indices:<pre>type EntryIxs = '[Author, Id, Updated, Test] type
--   IxEntry = IxSet EntryIxs Entry instance Indexable EntryIxs Entry where
--   indices = ixList (ixGen (Proxy :: Proxy Author)) -- out of order
--   (ixGen (Proxy :: Proxy Id)) (ixGen (Proxy :: Proxy Updated)) (ixGen
--   (Proxy :: Proxy Test)) -- bogus index</pre>The use of <a>ixGen</a>
--   requires the <a>Data</a> and <a>Typeable</a> instances above. You can
--   build indices manually using <a>ixFun</a>. You can also use the
--   Template Haskell function <a>inferIxSet</a> to generate an
--   <a>Indexable</a> instance automatically.</li>
--   <li>Use <a>insert</a>, <a>insertList</a>, <a>delete</a>,
--   <a>updateIx</a>, <a>deleteIx</a> and <a>empty</a> to build up an
--   <a>IxSet</a> collection:<pre>entries = insertList [e1, e2, e3, e4]
--   (empty :: IxEntry) entries1 = foldr delete entries [e1, e3] entries2 =
--   updateIx (Id 4) e5 entries</pre></li>
--   <li>Use the query functions below to grab data from it:<pre>entries @=
--   Author "john@doe.com" @&lt; Updated t1</pre>Statement above will find
--   all items in entries updated earlier than <tt>t1</tt> by
--   <tt>john@doe.com</tt>.</li>
--   <li>Text indexIf you want to do add a text index create a calculated
--   index. Then if you want all entries with either <tt>word1</tt> or
--   <tt>word2</tt>, you change the instance to:<pre>newtype Word = Word
--   String deriving (Show, Eq, Ord) getWords (Entry _ _ _ _ (Content s)) =
--   map Word $ words s type EntryIxs = '[..., Word] instance Indexable
--   EntryIxs Entry where indices = ixList ... (ixFun getWords)</pre>Now
--   you can do this query to find entries with any of the
--   words:<pre>entries @+ [Word "word1", Word "word2"]</pre>And if you
--   want all entries with both:<pre>entries @* [Word "word1", Word
--   "word2"]</pre></li>
--   <li>Find only the first authorIf an <tt>Entry</tt> has multiple
--   authors and you want to be able to query on the first author only,
--   define a <tt>FirstAuthor</tt> datatype and create an index with this
--   type. Now you can do:<pre>newtype FirstAuthor = FirstAuthor Email
--   deriving (Show, Eq, Ord) getFirstAuthor (Entry author _ _ _ _) =
--   [FirstAuthor author] type EntryIxs = '[..., FirstAuthor] instance
--   Indexable EntryIxs Entry where indices = ixList ... (ixFun
--   getFirstAuthor)</pre><pre>entries @= (FirstAuthor "john@doe.com") --
--   guess what this does</pre></li>
--   </ol>
module Data.IxSet.Typed

-- | Set with associated indices.
--   
--   The type-level list <tt>ixs</tt> contains all types that are valid
--   index keys. The type <tt>a</tt> is the type of elements in the indexed
--   set.
--   
--   On strictness: An <a>IxSet</a> is "mostly" spine-strict. It is
--   generally spine-strict in the set itself. All operations on
--   <a>IxSet</a> with the exception of queries are spine-strict in the
--   indices as well. Query operations, however, are lazy in the indices,
--   so querying a number of times and subsequently selecting the result
--   will not unnecessarily rebuild all indices.
data IxSet (ixs :: [*]) (a :: *)
data IxList (ixs :: [*]) (a :: *)

-- | Associate indices with a given type. The constraint
--   <tt><a>Indexable</a> ixs a</tt> says that we know how to build index
--   sets of type <tt><a>IxSet</a> ixs a</tt>.
--   
--   In order to use an <a>IxSet</a> on a particular type, you have to make
--   it an instance of <a>Indexable</a> yourself. There are no predefined
--   instances of <a>IxSet</a>.
class (All Ord ixs, Ord a) => Indexable ixs a

-- | Define how the indices for this particular type should look like.
--   
--   Use the <a>ixList</a> function to construct the list of indices, and
--   use <a>ixFun</a> (or <a>ixGen</a>) for individual indices.
indices :: Indexable ixs a => IxList ixs a

-- | Constraint for membership in the type-level list. Says that
--   <tt>ix</tt> is contained in the index list <tt>ixs</tt>.
class Ord ix => IsIndexOf (ix :: *) (ixs :: [*])

-- | The constraint <tt>All c xs</tt> says the <tt>c</tt> has to hold for
--   all elements in the type-level list <tt>xs</tt>.
--   
--   Example:
--   
--   <pre>
--   All Ord '[Int, Char, Bool]
--   </pre>
--   
--   is equivalent to
--   
--   <pre>
--   (Ord Int, Ord Char, Ord Bool)
--   </pre>

-- | <a>Ix</a> is a <a>Map</a> from some key (of type <tt>ix</tt>) to a
--   <a>Set</a> of values (of type <tt>a</tt>) for that key.
data Ix (ix :: *) (a :: *)

-- | Create an (empty) <a>IxList</a> from a number of indices. Useful in
--   the <a>Indexable</a> <a>indices</a> method. Use <a>ixFun</a> and
--   <a>ixGen</a> for the individual indices.
--   
--   Note that this function takes a variable number of arguments. Here are
--   some example types at which the function can be used:
--   
--   <pre>
--   ixList :: Ix ix1 a -&gt; IxList '[ix1] a
--   ixList :: Ix ix1 a -&gt; Ix ix2 a -&gt; IxList '[ix1, ix2] a
--   ixList :: Ix ix1 a -&gt; Ix ix2 a -&gt; Ix ix3 a -&gt; IxList '[ix1, ix2, ix3] a
--   ixList :: ...
--   </pre>
--   
--   Concrete example use:
--   
--   <pre>
--   instance Indexable '[..., Index1Type, Index2Type] Type where
--       indices = ixList
--                   ...
--                   (ixFun getIndex1)
--                   (ixGen (Proxy :: Proxy Index2Type))
--   </pre>
ixList :: MkIxList ixs ixs a r => r

-- | Class that allows a variable number of arguments to be passed to the
--   <tt>ixSet</tt> and <tt>mkEmpty</tt> functions. See the documentation
--   of these functions for more information.
class MkIxList ixs ixs' a r | r -> a ixs ixs'

-- | Create a functional index. Provided function should return a list of
--   indices where the value should be found.
--   
--   <pre>
--   getIndices :: Type -&gt; [IndexType]
--   getIndices value = [...indices...]
--   </pre>
--   
--   <pre>
--   instance Indexable '[IndexType] Type where
--       indices = ixList (ixFun getIndices)
--   </pre>
--   
--   This is the recommended way to create indices.
ixFun :: Ord ix => (a -> [ix]) -> Ix ix a

-- | Create a generic index. Provided example is used only as type source
--   so you may use a <tt>Proxy</tt>. This uses flatten to traverse values
--   using their <a>Data</a> instances.
--   
--   <pre>
--   instance Indexable '[IndexType] Type where
--       indices = ixList (ixGen (Proxy :: Proxy Type))
--   </pre>
--   
--   In production systems consider using <a>ixFun</a> in place of
--   <a>ixGen</a> as the former one is much faster.
ixGen :: forall proxy a ix. (Ord ix, Data a, Typeable ix) => proxy ix -> Ix ix a

-- | Function to be used as third argument in <a>inferIxSet</a> when you
--   don't want any calculated values.
noCalcs :: t -> ()

-- | Template Haskell helper function for automatically building an
--   <a>Indexable</a> instance from a data type, e.g.
--   
--   <pre>
--   data Foo = Foo Int String
--     deriving (Eq, Ord, Data, Typeable)
--   </pre>
--   
--   and
--   
--   <pre>
--   inferIxSet "FooDB" ''Foo 'noCalcs [''Int, ''String]
--   </pre>
--   
--   will define:
--   
--   <pre>
--   type FooDB = IxSet '[Int, String] Foo
--   instance Indexable '[Int, String] Foo where
--     ...
--   </pre>
--   
--   with <tt>Int</tt> and <tt>String</tt> as indices defined via
--   
--   <pre>
--   ixFun (flattenWithCalcs noCalcs)
--   </pre>
--   
--   each.
--   
--   <i>WARNING</i>: This function uses <a>flattenWithCalcs</a> for index
--   generation, which in turn uses an SYB type-based traversal. It is
--   often more efficient (and sometimes more correct) to explicitly define
--   the indices using <a>ixFun</a>.
inferIxSet :: String -> Name -> Name -> [Name] -> Q [Dec]
type IndexOp = forall k a. (Ord k, Ord a) => k -> a -> Map k (Set a) -> Map k (Set a)
type SetOp = forall a. Ord a => a -> Set a -> Set a

-- | Higher order operator for modifying <a>IxSet</a>s. Use this when your
--   final function should have the form <tt>a -&gt; <a>IxSet</a> a -&gt;
--   <a>IxSet</a> a</tt>, e.g. <a>insert</a> or <a>delete</a>.
change :: forall ixs a. Indexable ixs a => SetOp -> IndexOp -> a -> IxSet ixs a -> IxSet ixs a

-- | Inserts an item into the <a>IxSet</a>. If your data happens to have a
--   primary key this function might not be what you want. See
--   <a>updateIx</a>.
insert :: Indexable ixs a => a -> IxSet ixs a -> IxSet ixs a
insertList :: forall ixs a. Indexable ixs a => [a] -> IxSet ixs a -> IxSet ixs a

-- | Removes an item from the <a>IxSet</a>.
delete :: Indexable ixs a => a -> IxSet ixs a -> IxSet ixs a

-- | Will replace the item with the given index of type <tt>ix</tt>. Only
--   works if there is at most one item with that index in the
--   <a>IxSet</a>. Will not change <a>IxSet</a> if you have more than one
--   item with given index.
updateIx :: (Indexable ixs a, IsIndexOf ix ixs) => ix -> a -> IxSet ixs a -> IxSet ixs a

-- | Will delete the item with the given index of type <tt>ix</tt>. Only
--   works if there is at most one item with that index in the
--   <a>IxSet</a>. Will not change <a>IxSet</a> if you have more than one
--   item with given index.
deleteIx :: (Indexable ixs a, IsIndexOf ix ixs) => ix -> IxSet ixs a -> IxSet ixs a

-- | An empty <a>IxSet</a>.
empty :: Indexable ixs a => IxSet ixs a

-- | Converts a <a>Set</a> to an <a>IxSet</a>.
fromSet :: (Indexable ixs a) => Set a -> IxSet ixs a

-- | Converts a list to an <a>IxSet</a>.
fromList :: (Indexable ixs a) => [a] -> IxSet ixs a

-- | Converts an <a>IxSet</a> to a <a>Set</a> of its elements.
toSet :: IxSet ixs a -> Set a

-- | Converts an <a>IxSet</a> to its list of elements.
toList :: IxSet ixs a -> [a]

-- | Converts an <a>IxSet</a> to its list of elements.
--   
--   List will be sorted in ascending order by the index <tt>ix</tt>.
--   
--   The list may contain duplicate entries if a single value produces
--   multiple keys.
toAscList :: forall proxy ix ixs a. IsIndexOf ix ixs => proxy ix -> IxSet ixs a -> [a]

-- | Converts an <a>IxSet</a> to its list of elements.
--   
--   List will be sorted in descending order by the index <tt>ix</tt>.
--   
--   The list may contain duplicate entries if a single value produces
--   multiple keys.
toDescList :: forall proxy ix ixs a. IsIndexOf ix ixs => proxy ix -> IxSet ixs a -> [a]

-- | If the <a>IxSet</a> is a singleton it will return the one item stored
--   in it. If <a>IxSet</a> is empty or has many elements this function
--   returns <a>Nothing</a>.
getOne :: Ord a => IxSet ixs a -> Maybe a

-- | Like <a>getOne</a> with a user-provided default.
getOneOr :: Ord a => a -> IxSet ixs a -> a

-- | Returns the number of unique items in the <a>IxSet</a>.
size :: IxSet ixs a -> Int

-- | Return <a>True</a> if the <a>IxSet</a> is empty, <a>False</a>
--   otherwise.
null :: IxSet ixs a -> Bool

-- | An infix <a>intersection</a> operation.
(&&&) :: Indexable ixs a => IxSet ixs a -> IxSet ixs a -> IxSet ixs a
infixr 5 &&&

-- | An infix <a>union</a> operation.
(|||) :: Indexable ixs a => IxSet ixs a -> IxSet ixs a -> IxSet ixs a
infixr 5 |||

-- | Takes the union of the two <a>IxSet</a>s.
union :: Indexable ixs a => IxSet ixs a -> IxSet ixs a -> IxSet ixs a

-- | Takes the intersection of the two <a>IxSet</a>s.
intersection :: Indexable ixs a => IxSet ixs a -> IxSet ixs a -> IxSet ixs a

-- | Infix version of <a>getEQ</a>.
(@=) :: (Indexable ixs a, IsIndexOf ix ixs) => IxSet ixs a -> ix -> IxSet ixs a

-- | Infix version of <a>getLT</a>.
(@<) :: (Indexable ixs a, IsIndexOf ix ixs) => IxSet ixs a -> ix -> IxSet ixs a

-- | Infix version of <a>getGT</a>.
(@>) :: (Indexable ixs a, IsIndexOf ix ixs) => IxSet ixs a -> ix -> IxSet ixs a

-- | Infix version of <a>getLTE</a>.
(@<=) :: (Indexable ixs a, IsIndexOf ix ixs) => IxSet ixs a -> ix -> IxSet ixs a

-- | Infix version of <a>getGTE</a>.
(@>=) :: (Indexable ixs a, IsIndexOf ix ixs) => IxSet ixs a -> ix -> IxSet ixs a

-- | Returns the subset with indices in the open interval (k,k).
(@><) :: (Indexable ixs a, IsIndexOf ix ixs) => IxSet ixs a -> (ix, ix) -> IxSet ixs a

-- | Returns the subset with indices in [k,k).
(@>=<) :: (Indexable ixs a, IsIndexOf ix ixs) => IxSet ixs a -> (ix, ix) -> IxSet ixs a

-- | Returns the subset with indices in (k,k].
(@><=) :: (Indexable ixs a, IsIndexOf ix ixs) => IxSet ixs a -> (ix, ix) -> IxSet ixs a

-- | Returns the subset with indices in [k,k].
(@>=<=) :: (Indexable ixs a, IsIndexOf ix ixs) => IxSet ixs a -> (ix, ix) -> IxSet ixs a

-- | Creates the subset that has an index in the provided list.
(@+) :: (Indexable ixs a, IsIndexOf ix ixs) => IxSet ixs a -> [ix] -> IxSet ixs a

-- | Creates the subset that matches all the provided indices.
(@*) :: (Indexable ixs a, IsIndexOf ix ixs) => IxSet ixs a -> [ix] -> IxSet ixs a

-- | Returns the subset with an index equal to the provided key. The set
--   must be indexed over key type, doing otherwise results in runtime
--   error.
getEQ :: (Indexable ixs a, IsIndexOf ix ixs) => ix -> IxSet ixs a -> IxSet ixs a

-- | Returns the subset with an index less than the provided key. The set
--   must be indexed over key type, doing otherwise results in runtime
--   error.
getLT :: (Indexable ixs a, IsIndexOf ix ixs) => ix -> IxSet ixs a -> IxSet ixs a

-- | Returns the subset with an index greater than the provided key. The
--   set must be indexed over key type, doing otherwise results in runtime
--   error.
getGT :: (Indexable ixs a, IsIndexOf ix ixs) => ix -> IxSet ixs a -> IxSet ixs a

-- | Returns the subset with an index less than or equal to the provided
--   key. The set must be indexed over key type, doing otherwise results in
--   runtime error.
getLTE :: (Indexable ixs a, IsIndexOf ix ixs) => ix -> IxSet ixs a -> IxSet ixs a

-- | Returns the subset with an index greater than or equal to the provided
--   key. The set must be indexed over key type, doing otherwise results in
--   runtime error.
getGTE :: (Indexable ixs a, IsIndexOf ix ixs) => ix -> IxSet ixs a -> IxSet ixs a

-- | Returns the subset with an index within the interval provided. The
--   bottom of the interval is closed and the top is open, i. e. [k1;k2).
--   The set must be indexed over key type, doing otherwise results in
--   runtime error.
getRange :: (Indexable ixs a, IsIndexOf ix ixs) => ix -> ix -> IxSet ixs a -> IxSet ixs a

-- | Returns lists of elements paired with the indices determined by type
--   inference.
groupBy :: forall ix ixs a. IsIndexOf ix ixs => IxSet ixs a -> [(ix, [a])]

-- | Returns lists of elements paired with the indices determined by type
--   inference.
--   
--   The resulting list will be sorted in ascending order by <tt>ix</tt>.
--   The values in <tt>[a]</tt> will be sorted in ascending order as well.
groupAscBy :: forall ix ixs a. IsIndexOf ix ixs => IxSet ixs a -> [(ix, [a])]

-- | Returns lists of elements paired with the indices determined by type
--   inference.
--   
--   The resulting list will be sorted in descending order by <tt>ix</tt>.
--   
--   NOTE: The values in <tt>[a]</tt> are currently sorted in ascending
--   order. But this may change if someone bothers to add
--   <a>toDescList</a>. So do not rely on the sort order of the resulting
--   list.
groupDescBy :: IsIndexOf ix ixs => IxSet ixs a -> [(ix, [a])]

-- | Generically traverses the argument to find all occurences of values of
--   type <tt>b</tt> and returns them as a list.
--   
--   This function properly handles <a>String</a> as <a>String</a> not as
--   <tt>[<a>Char</a>]</tt>.
flatten :: (Typeable a, Data a, Typeable b) => a -> [b]

-- | Generically traverses the argument and calculated values to find all
--   occurences of values of type <tt>b</tt> and returns them as a list.
--   Equivalent to:
--   
--   <pre>
--   flatten (x,calcs x)
--   </pre>
--   
--   This function properly handles <a>String</a> as <a>String</a> not as
--   <tt>[<a>Char</a>]</tt>.
flattenWithCalcs :: (Data c, Typeable a, Data a, Typeable b) => (a -> c) -> a -> [b]

-- | Statistics about <a>IxSet</a>. This function returns quadruple
--   consisting of
--   
--   <ol>
--   <li>total number of elements in the set</li>
--   <li>number of declared indices</li>
--   <li>number of keys in all indices</li>
--   <li>number of values in all keys in all indices.</li>
--   </ol>
--   
--   This can aid you in debugging and optimisation.
stats :: Indexable ixs a => IxSet ixs a -> (Int, Int, Int, Int)
instance GHC.Classes.Ord ix => Data.IxSet.Typed.IsIndexOf ix (ix : ixs)
instance Data.IxSet.Typed.IsIndexOf ix ixs => Data.IxSet.Typed.IsIndexOf ix (ix' : ixs)
instance Data.IxSet.Typed.Indexable ixs a => GHC.Classes.Eq (Data.IxSet.Typed.IxSet ixs a)
instance Data.IxSet.Typed.Indexable ixs a => GHC.Classes.Ord (Data.IxSet.Typed.IxSet ixs a)
instance (Data.IxSet.Typed.Indexable ixs a, GHC.Show.Show a) => GHC.Show.Show (Data.IxSet.Typed.IxSet ixs a)
instance (Data.IxSet.Typed.Indexable ixs a, GHC.Read.Read a) => GHC.Read.Read (Data.IxSet.Typed.IxSet ixs a)
instance (Data.IxSet.Typed.Indexable ixs a, Data.SafeCopy.SafeCopy.SafeCopy a) => Data.SafeCopy.SafeCopy.SafeCopy (Data.IxSet.Typed.IxSet ixs a)
instance (Data.IxSet.Typed.All Control.DeepSeq.NFData ixs, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Data.IxSet.Typed.IxList ixs a)
instance (Data.IxSet.Typed.All Control.DeepSeq.NFData ixs, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Data.IxSet.Typed.IxSet ixs a)
instance Data.IxSet.Typed.Indexable ixs a => GHC.Base.Monoid (Data.IxSet.Typed.IxSet ixs a)
instance Data.Foldable.Foldable (Data.IxSet.Typed.IxSet ixs)
instance Data.IxSet.Typed.MkIxList '[] ixs a (Data.IxSet.Typed.IxList ixs a)
instance Data.IxSet.Typed.MkIxList ixs ixs' a r => Data.IxSet.Typed.MkIxList (ix : ixs) ixs' a (Data.IxSet.Typed.Ix.Ix ix a -> r)
