reflection-1.4: Reifies arbitrary terms into types that can be reflected back into terms

MaintainerEdward Kmett <>
Safe HaskellTrustworthy




Reifies arbitrary terms at the type level. Based on the Functional Pearl: Implicit Configurations paper by Oleg Kiselyov and Chung-chieh Shan.

The approach from the paper was modified to work with Data.Proxy and to cheat by using knowledge of GHC's internal representations by Edward Kmett and Elliott Hird.

Usage comes down to two combinators, reify and reflect.

>>> reify 6 (\p -> reflect p + reflect p)

The argument passed along by reify is just a data Proxy t = Proxy, so all of the information needed to reconstruct your value has been moved to the type level. This enables it to be used when constructing instances (see examples/Monoid.hs).

In addition, a simpler API is offered for working with singleton values such as a system configuration, etc.



class Reifies s a | s -> a whereSource


reflect :: proxy s -> aSource

Recover a value inside a reify context, given a proxy for its reified type.


Reifies * Z Int 
Reifies * n Int => Reifies * (PD n) Int 
Reifies * n Int => Reifies * (SD n) Int 
Reifies * n Int => Reifies * (D n) Int 

reify :: forall a r. a -> (forall s. Reifies s a => Proxy s -> r) -> rSource

Reify a value at the type level, to be recovered with reflect.


class Given a whereSource

This is a version of Reifies that allows for only a single value.

This is easier to work with than Reifies and permits extended defaulting, but it only offers a single reflected value of a given type at a time.


given :: aSource

Recover the value of a given type previously encoded with give.

give :: forall a r. a -> (Given a => r) -> rSource

Reify a value into an instance to be recovered with given.

You should only give a single value for each type. If multiple instances are in scope, then the behavior is implementation defined.

Template Haskell reflection

int :: Int -> TypeQSource

This can be used to generate a template haskell splice for a type level version of a given int.

This does not use GHC TypeLits, instead it generates a numeric type by hand similar to the ones used in the "Functional Pearl: Implicit Configurations" paper by Oleg Kiselyov and Chung-Chieh Shan.

instance Num (Q Exp) provided in this package allows writing $(3) instead of $(int 3). Sometimes the two will produce the same representation (if compiled without the -DUSE_TYPE_LITS preprocessor directive).

nat :: Int -> TypeQSource

This is a restricted version of int that can only generate natural numbers. Attempting to generate a negative number results in a compile time error. Also the resulting sequence will consist entirely of Z, D, and SD constructors representing the number in zeroless binary.

Useful compile time naturals

data Z Source


data D n Source


Reifies * n Int => Reifies * (D n) Int 

data SD n Source


Reifies * n Int => Reifies * (SD n) Int 

data PD n Source


Reifies * n Int => Reifies * (PD n) Int