Safe Haskell | None |
---|---|
Language | Haskell2010 |
Control.IndexT.Tuple
Description
Type family and class definitions for dealing with tuples.
See the Control.IndexT module description for an overview.
- type family TupleN (n :: Nat) a
- type TupleConstraint n a = a ~ TupleN n a
- type family HomoTupleConstraint (n :: Nat) a :: Constraint
- class TupleConstraint n a => IsTuple n a
- class HomoTupleConstraint n a => IsHomoTuple n a
Documentation
type family TupleN (n :: Nat) a Source #
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
.
Instances
type TupleN 0 a Source # | |
type TupleN 1 a Source # | |
type TupleN 2 a Source # | |
type TupleN 3 a Source # | |
type TupleN 4 a Source # | |
type TupleN 5 a Source # | |
type TupleN 6 a Source # | |
type TupleN 7 a Source # | |
type TupleN 8 a Source # | |
type TupleN 9 a Source # | |
type TupleN 10 a Source # | |
type TupleN 11 a Source # | |
type TupleN 12 a Source # | |
type TupleN 13 a Source # | |
type TupleN 14 a Source # | |
type TupleN 15 a Source # | |
type TupleConstraint n a = a ~ TupleN n a Source #
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 family HomoTupleConstraint (n :: Nat) a :: Constraint Source #
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.)
Instances
type HomoTupleConstraint 0 a Source # | |
type HomoTupleConstraint 1 a Source # | |
type HomoTupleConstraint 2 a Source # | |
type HomoTupleConstraint 3 a Source # | |
type HomoTupleConstraint 4 a Source # | |
type HomoTupleConstraint 5 a Source # | |
type HomoTupleConstraint 6 a Source # | |
type HomoTupleConstraint 7 a Source # | |
type HomoTupleConstraint 8 a Source # | |
type HomoTupleConstraint 9 a Source # | |
type HomoTupleConstraint 10 a Source # | |
type HomoTupleConstraint 11 a Source # | |
type HomoTupleConstraint 12 a Source # | |
type HomoTupleConstraint 13 a Source # | |
type HomoTupleConstraint 14 a Source # | |
type HomoTupleConstraint 15 a Source # | |
class TupleConstraint n a => IsTuple n a Source #
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.
Instances
TupleConstraint n a => IsTuple n a Source # | |
class HomoTupleConstraint n a => IsHomoTuple n a Source #
The version of IsTuple
for homogenous tuples (i.e. all the same type).
Instances
HomoTupleConstraint n a => IsHomoTuple n a Source # | |