kind-apply-0.3.2.0: Utilities to work with lists of types

Data.PolyKinded

Synopsis

# Lists of types and application

data LoT k where Source #

LoT k represents a list of types which can be applied to a data type of kind k.

Constructors

 LoT0 :: LoT * Empty list of types. (:&&:) :: k -> LoT ks -> LoT (k -> ks) infixr 5 Cons a type with a list of types.

type family (f :: k) :@@: (tys :: LoT k) :: * where ... Source #

Apply a list of types to a type constructor.

>>> :kind! Either :@@: (Int :&&: Bool :&&: LoT0)
Either Int Bool :: *


Equations

 f :@@: _ = f f :@@: as = f (HeadLoT as) :@@: TailLoT as

type LoT1 a = a :&&: LoT0 Source #

type LoT2 a b = a :&&: (b :&&: LoT0) Source #

type family HeadLoT (tys :: LoT (k -> k')) :: k where ... Source #

Head of a non-empty list of types.

>>> :kind! HeadLoT (Int :&&: LoT0)
Int :: *


Equations

 HeadLoT (a :&&: _) = a

type family TailLoT (tys :: LoT (k -> k')) :: LoT k' where ... Source #

Tail of a non-empty list of types.

>>> :kind! TailLoT (Int :&&: Bool :&&: LoT0)
Bool :&&: LoT0 :: LoT (Type -> Type)


Equations

 TailLoT (_ :&&: as) = as

type family SpineLoT (ts :: LoT k) :: LoT k where ... Source #

Construct the spine of a list of types whose length is known.

It can be useful to introduce unification variables for lists of types which will be fully instantiated during constraint resolution. A constraint p ~ SpineLoT p will thus instantiate the spine of p.

On concrete lists, this is the identity function.

Equations

 SpineLoT (ts :: LoT (k -> k')) = HeadLoT ts :&&: SpineLoT (TailLoT ts) SpineLoT (ts :: LoT *) = LoT0

## Singleton for list of types

data SLoT (l :: LoT k) where Source #

Constructors

 SLoT0 :: SLoT LoT0 SLoTA :: Proxy t -> SLoT ts -> SLoT (t :&&: ts)

class SForLoT (l :: LoT k) where Source #

Methods

Instances
 l ~ LoT0 => SForLoT (l :: LoT Type) Source # Instance detailsDefined in Data.PolyKinded Methods (l ~ (t :&&: ts), SForLoT ts) => SForLoT (l :: LoT (k -> k')) Source # Instance detailsDefined in Data.PolyKinded Methods

data Proxy (t :: k) :: forall k. k -> Type #

Proxy is a type that holds no data, but has a phantom parameter of arbitrary type (or even kind). Its use is to provide type information, even though there is no value available of that type (or it may be too costly to create one).

Historically, Proxy :: Proxy a is a safer alternative to the 'undefined :: a' idiom.

>>> Proxy :: Proxy (Void, Int -> Int)
Proxy


Proxy can even hold types of higher kinds,

>>> Proxy :: Proxy Either
Proxy

>>> Proxy :: Proxy Functor
Proxy

>>> Proxy :: Proxy complicatedStructure
Proxy


Constructors

 Proxy
Instances

# Splitting types

type SplitF (t :: d) (f :: k) = SplitF' t f LoT0 Source #

Split a type t until the constructor f is found.

>>> :kind! SplitF (Either Int Bool) Either
Int :&&: Bool :&&: LoT0 :: LoT (* -> * -> *)
>>> :kind! SplitF (Either Int Bool) (Either Int)
Bool :&&: LoT0 :: LoT (* -> *)


data Nat Source #

Simple natural numbers.

Constructors

 Z S Nat

data TyEnv where Source #

A type constructor and a list of types that can be applied to it.

Constructors

 TyEnv :: forall k. k -> LoT k -> TyEnv

type family SplitN (n :: Nat) t :: TyEnv where ... Source #

Split a type t until its list of types has length n.

>>> :kind! SplitN (Either Int Bool) (S (S Z))
TyEnv Either (Int :&&: Bool :&&: LoT0) :: TyEnv
>>> :kind! SplitF (Either Int Bool) (S Z)
TyEnv (Either Int) (Bool :&&: LoT0) :: TyEnv


Equations

 SplitN n t = SplitN' n t LoT0