Higher-order functional programming in PureScript's type system.
Inspired by Haskell with only one type family.
This library exports a typeclass Eval
which lets us evaluate type-level
expressions of kind TypeExpr
. A TypeExpr
evaluates to something of kind
Type
. With this we can do lazy, higher-order functional programming
to compute types and their relationships.
Take an input row, and compute a row where all the types are String
:
type RowToString =
ToRow <<< Map (Const String) <<< FromRow
test :: forall ri ro.
Eval (RowToString ri) ro =>
{ | ri } ->
{ | ro } ->
Unit
test _ _ = Unit
Assert that all rows have a type String
:
type RowAllString =
Assert "Only String is allowed" <<< All (Eq String) <<< FromRow
test :: forall ri.
Eval (RowAllString ri) Unit =>
{ | ri } ->
Unit
test _ = Unit
With Type.Eval.ValueOf
we can emulate Haskell's Type Families via explicit coercions.
foreign import data Elem :: Type -> TypeExpr
instance evalElemString :: Eval (Elem String) Char
instance evalElemArray :: Eval (Elem (Array a)) a
testValue :: ValueOf (Elem String)
testValue = ValueOf.from 'a'
test :: Char
test = ValueOf.to testValue
Note that you can use any TypeExpr
to tag a ValueOf
.