Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
Converts function arguments to tuple-like types.
For example, take f :: a -> b -> c -> r
.
This module can convert it to f' :: (a, b, c) -> r
, at compile time.
This is especially useful for (de)serialization. Suppose you have a function that takes multiple arguments and you want to obtain all of its arguments from some serialized data. The serialization library will make it very easy to unpack types like tuples/lists, but de-serializing *fuction arguments* is not that simple.
Using this module, you can write an instance how to unpack the TypeList
type,
and then use translateCall
to make any function take such a single TypeList
instead of multiple function arguments.
There is currently a technical limitation:
The result type must be wrapped in the Identity
monad.
Example:
-- Assume your library provides some unpack function, e.g. it allows you to write: unpack someBytestring :: (Int, String, Double) -- and you have a function f :: Int -> String -> Double -> Identity Char -- then you can use: f' :: (Int, String, Double) -> Identity Char f' = translateCall f result = f' (unpack someBytestring)
- data TypeList l where
- type family Param f :: [*]
- type family Result f :: *
- class (Param f ~ l, Result f ~ r) => ToTypeList f l r where
- data Proxy k = Proxy
- class ParamLength l where
- paramLength :: Proxy l -> Int
Type-level lists (containing types)
Type-level list that can contain arbitrarily mixed types.
Example:
1 ::: "hello" ::: 2.3 :: TypeList '[Int, String, Double]
"Uncurrying" functions
type family Param f :: [*] Source
Arguments to a function, e.g. [String, Int]
for String -> Int -> r
.
class (Param f ~ l, Result f ~ r) => ToTypeList f l r where Source
Function f can be translated to TypeList
l with result type r.
translate :: f -> TypeList l -> r Source
Translates a function taking multiple arguments to a function
taking a single TypeList
containing the types of all arguments.
Example: t1 -> ... -> tn -> r
becomes TypeList [t1, ..., tn] -> r
.
ToTypeList (Identity r) ([] *) r Source | Recursive case: A function of type |
ToTypeList (IO r) ([] *) (IO r) Source | Base case: An IO function without arguments (just |
ToTypeList f l r => ToTypeList (a -> f) ((:) * a l) r Source | Base case: A "pure" function without arguments (just |
Length of type-level lists
A proxy type that can contain an arbitrary type.
Needed for some type-level computations, like paramLength
.
class ParamLength l where Source
paramLength :: Proxy l -> Int Source
Calculates the length of a type list, put into a proxy. Usage:
paramLength (undefined :: Proxy l)
ParamLength ([] *) Source | |
ParamLength l => ParamLength ((:) * a l) Source |