-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A series of type families and constraints for "indexable" types. -- -- This package deals with types that can roughly be "indexed" at compile -- time by an integer. For example, tuples and be indexed by their nth -- elements, and functions by their nth argument. A number of type -- functions allow one to extract these subtypes, i.e. the type of the -- 2nd element of a given tuple. Furthermore, constraints are defined -- which allow one to easily constrain types to these index types, e.g. a -- constraint that says "t is a 3 tuple". Control.IndexT -- has more detail. @package indextype @version 0.2.2.0 -- | This module just has the IndexT type extraction function but -- raised to type level module Control.IndexT.TypeLevel -- | IndexT on polykinded type level tuples. -- -- Note this currently is only defined on tuples. -- | Type family and class definitions for dealing with tuples. -- -- Control.IndexT.Tuple but with tuples raised to the type level -- and polykinded. module Control.IndexT.TypeLevel.Tuple -- | Type level version of TupleConstraint -- | HomoTupleConstraint simply further constrains -- TupleConstraint so that all the elements are the same. -- -- So HomoTupleConstraint 3 t basically says t ~ -- (u,u,u) for some u, -- -- ("Homo" is short for "Homogeneous". As in, all the same. Or like -- milk.) -- | GHC does not allow you to partially apply type families (or any type -- declaration for that matter). So if you have a type of * -> -- Constraint you can't pass TupleConstraint 2, because -- TupleConstraint is partially applied and this is not allowed. -- -- But you can partially apply classes. -- -- So IsTuple is basically the same as TupleConstraint -- except that it's a class, not a type family. class (TupleConstraint n a) => IsTuple n a -- | The version of IsTuple for homogenous tuples (i.e. all the same -- type). class (HomoTupleConstraint n a) => IsHomoTuple n a instance forall k (n :: GHC.Types.Nat) (a :: k). Control.IndexT.TypeLevel.Tuple.TupleConstraint n a => Control.IndexT.TypeLevel.Tuple.IsTuple n a instance Control.IndexT.TypeLevel.Tuple.HomoTupleConstraint n a => Control.IndexT.TypeLevel.Tuple.IsHomoTuple n a -- | This module provides a way to constrain types to be data constructors, -- much like Control.IndexT.Tuple and -- Control.IndexT.Function. -- -- It also provides type families for accessing the elements of those -- data constructors, both the constructors themselves and the parameters -- to them. -- -- Note I haven't yet wrote code to generate many instances for these, so -- currently only constructors with up to two parameters is supported. -- Just nag me if your application needs more. module Control.IndexT.Constructor -- |
-- IndexC i n (f a_0 a_1 .. a_(n-1)) ---- -- the ith (zero based) parameter of the constructor with n parameters, -- i.e. a_i -- | Much like IsTuple and IsFunction, IsData m t -- asserts that t is a data constructor with n -- variables. -- | This package is useful for dealing with for what I have called -- "indexed types". This is perhaps not a great choice of name -- (alternative suggestions welcome) but basically I'm talking about -- types where you can "index" them like an array. A tuple is a good -- example. -- -- This particular module gives you a type function IndexT that -- allows you to get the type of the say, third element of a tuple. -- -- But the other modules in this package, Control.IndexT.Tuple and -- Control.IndexT.Function, build on this. -- -- For example, occasionally you'll want to write a constraint like this: -- --
-- t ~ (t1,t2) ---- -- i.e. t is a pair. But if t1 and t2 are not -- in scope, GHC will complain. -- -- This package contains some type family and class defined constraints -- that allow you to make constraints like "t is a pair". -- -- The type families are open, so you can extend this module for your own -- data types. -- -- More detailed usage information is in the documentation, both below. -- and also in Control.IndexT.Tuple. -- -- Currently this library deals with tuples up to length 15 and functions -- with up to 15 arguments. Let me know if you need anything bigger. module Control.IndexT -- | IndexT is the core type family of this module. IndexT n -- a gets the type of the "nth" element of a. In this -- module, IndexT is defined on tuples and functions, and is zero -- based. -- -- So -- --
-- IndexT 0 (a, b, c) == a ---- -- and -- --
-- IndexT 0 (a -> b -> c) == a ---- -- Note the following: -- --
-- IndexT 1 (a -> b -> c) == b -- IndexT 2 (a, b, c) == c ---- -- but... -- --
-- IndexT 2 (a -> b -> c) /= c -- (it's actually not defined) ---- -- This is because the way functions are defined. Consider a function of -- three arguments: -- --
-- f :: a -> b -> c -> d ---- -- For this function, we want: -- --
-- IndexT 2 (a -> b -> c -> d) == c ---- -- But if we defined IndexT like the following: -- --
-- IndexT 2 (a -> b -> c) = c ---- -- Then we would find that: -- --
-- IndexT 2 (a -> b -> c -> d) == IndexT 2 (a -> b -> (c -> d)) == (c -> d) ---- -- Which is not right. For this reason, IndexT can not get the -- "result" type of functions, you'll need to use ResultT for -- that. -- | Type family and class definitions for dealing with functions. -- -- Many of these definitions are similar to the ones that deal with -- tuples, in which case it refers to the documentation in -- Control.IndexT.Tuple. -- -- Also see the Control.IndexT module description for an overview. module Control.IndexT.Function -- | ResultT is used to get the result type of functions, which -- IndexT can not be used for as discussed in it's documentation. -- -- ResultT n t gets the result of t treated as an -- n argument function. For example: -- --
-- ResultT 2 (a -> b -> c) == c ---- -- note that: -- --
-- ResultT 2 (a -> b -> c -> d) == c -> d ---- -- which makes sense, as the result of applying two arguments to this -- function is (c -> d). -- | Like TupleN, but for functions. -- | Like TupleConstraint, but for functions. type FuncConstraint (n :: Nat) a = a ~ FuncN n a -- | Like HomoTupleConstraint, but for functions, where all -- arguments and the result type are the same. type HomoFuncConstraint (n :: Nat) a = (HomoArgFuncConstraint n a, ResultT n a ~ IndexT 0 a) -- | Like HomoFuncConstraint, but only constrains all the arguments -- to be the same type, not the result. -- | Like IsTuple, but for functions. class (FuncConstraint n a) => IsFunc n a -- | Like IsHomoTuple, but for functions. class (HomoFuncConstraint n a) => IsHomoFunc n a -- | A classed based constraint for HomoArgFuncConstraint. class (HomoArgFuncConstraint n a) => IsHomoArgFunc n a instance Control.IndexT.Function.FuncConstraint n a => Control.IndexT.Function.IsFunc n a instance Control.IndexT.Function.HomoFuncConstraint n a => Control.IndexT.Function.IsHomoFunc n a instance Control.IndexT.Function.HomoArgFuncConstraint n a => Control.IndexT.Function.IsHomoArgFunc n a -- | Type family and class definitions for dealing with tuples. -- -- See the Control.IndexT module description for an overview. module Control.IndexT.Tuple -- | TupleN seems a bit weird, but it's an important part of -- defining constraints that allow one to say "t is a pair" in -- TupleConstraint. -- | To best explain this, lets consider the particular example -- TupleConstraint 2. -- -- As TupleN 2 t = (IndexT 0 t, IndexT 1 t) we get: -- --
-- TupleConstraint 2 t = t ~ (IndexT 0 t, IndexT 1 t) ---- -- What does this say? Well, firstly, as t ~ (IndexT 0 t, IndexT 1 -- t), it must be a pair at least. -- -- What are the elements of the pair? Well, the first element of -- t is IndexT 0 t. -- -- And what's IndexT 0 t defined as? The first element of -- t. -- -- So we know that the first element of t is well, the first -- element of t. -- -- Which tells us nothing at all. -- -- We can go through the same argument with the second element of -- t. -- -- So all we know after this is that t is a pair. -- TupleConstraint 2 t is the same as saying t is a -- pair. -- -- So TupleConstraint n t basically says t is a -- n-tuple. type TupleConstraint (n :: Nat) a = a ~ TupleN n a -- | HomoTupleConstraint simply further constrains -- TupleConstraint so that all the elements are the same. -- -- So HomoTupleConstraint 3 t basically says t ~ -- (u,u,u) for some u, -- -- ("Homo" is short for "Homogeneous". As in, all the same. Or like -- milk.) -- | GHC does not allow you to partially apply type families (or any type -- declaration for that matter). So if you have a type of * -> -- Constraint you can't pass TupleConstraint 2, because -- TupleConstraint is partially applied and this is not allowed. -- -- But you can partially apply classes. -- -- So IsTuple is basically the same as TupleConstraint -- except that it's a class, not a type family. class (TupleConstraint n a) => IsTuple n a -- | The version of IsTuple for homogenous tuples (i.e. all the same -- type). class (HomoTupleConstraint n a) => IsHomoTuple n a instance Control.IndexT.Tuple.TupleConstraint n a => Control.IndexT.Tuple.IsTuple n a instance Control.IndexT.Tuple.HomoTupleConstraint n a => Control.IndexT.Tuple.IsHomoTuple n a