datafix-0.0.0.2: Fixing data-flow problems

Copyright(c) Sebastian Graf 2018
LicenseISC
Maintainersgraf1337@gmail.com
Portabilityportable
Safe HaskellNone
LanguageHaskell2010

Datafix.Utils.TypeLevel

Description

Some type-level helpers for 'curry'/'uncurry'ing arbitrary function types.

Synopsis

Documentation

type family All (p :: k -> Constraint) (as :: [k]) :: Constraint where ... Source #

All p as ensures that the constraint p is satisfied by all the types in as. (Types is between scare-quotes here because the code is actually kind polymorphic)

Equations

All p '[] = () 
All p (a ': as) = (p a, All p as) 

type family If (b :: Bool) (l :: k) (r :: k) :: k where ... Source #

On Booleans

Equations

If True l r = l 
If False l r = r 

type family Foldr (c :: k -> l -> l) (n :: l) (as :: [k]) :: l where ... Source #

On Lists

Equations

Foldr c n '[] = n 
Foldr c n (a ': as) = c a (Foldr c n as) 

type family Foldr' (c :: Function k (Function l l -> *) -> *) (n :: l) (as :: [k]) :: l where ... Source #

Version of Foldr taking a defunctionalised argument so that we can use partially applied functions.

Equations

Foldr' c n '[] = n 
Foldr' c n (a ': as) = Apply (Apply c a) (Foldr' c n as) 

type family Map (f :: Function k l -> *) (as :: [k]) :: [l] where ... Source #

Equations

Map f as = Foldr' (ConsMap0 f) '[] as 

data ConsMap0 :: (Function k l -> *) -> Function k (Function [l] [l] -> *) -> * Source #

Instances

type Apply k (Function [l] [l] -> *) (ConsMap0 k l f) a Source # 
type Apply k (Function [l] [l] -> *) (ConsMap0 k l f) a = ConsMap1 k l f a

data ConsMap1 :: (Function k l -> *) -> k -> Function [l] [l] -> * Source #

Instances

type Apply [a1] [a1] (ConsMap1 k a1 f a2) tl Source # 
type Apply [a1] [a1] (ConsMap1 k a1 f a2) tl = (:) a1 (Apply k a1 f a2) tl

type family Constant (b :: l) (as :: [k]) :: [l] where ... Source #

Equations

Constant b as = Map (Constant1 b) as 

type Arrows (as :: [*]) (r :: *) = Foldr (->) r as Source #

Arrows [a1,..,an] r corresponds to a1 -> .. -> an -> r

type family Products (as :: [*]) where ... Source #

Products [] corresponds to (), Products [a] corresponds to a, Products [a1,..,an] corresponds to (a1, (..,( an)..)).

So, not quite a right fold, because we want to optimize for the empty, singleton and pair case.

Equations

Products '[] = () 
Products '[a] = a 
Products (a ': as) = (a, Products as) 

type family IsBase (t :: *) :: Bool where ... Source #

IsBase t is 'True whenever t is *not* a function space.

Equations

IsBase (a -> t) = False 
IsBase a = True 

type family ParamTypes (t :: *) :: [*] where ... Source #

Using IsBase we can define notions of ParamTypes and ReturnTypes which *reduce* under positive information IsBase t ~ 'True even though the shape of t is not formally exposed

Equations

ParamTypes t = If (IsBase t) '[] (ParamTypes' t) 

type family ParamTypes' (t :: *) :: [*] where ... Source #

Equations

ParamTypes' (a -> t) = a ': ParamTypes t 

type family ReturnType (t :: *) :: * where ... Source #

Equations

ReturnType t = If (IsBase t) t (ReturnType' t) 

type family ReturnType' (t :: *) :: * where ... Source #

Equations

ReturnType' (a -> t) = ReturnType t 

class Currying as b where Source #

Currying as b witnesses the isomorphism between Arrows as b and Products as -> b. It is defined as a type class rather than by recursion on a singleton for as so all of that these conversions are inlined at compile time for concrete arguments.

Minimal complete definition

uncurrys, currys

Methods

uncurrys :: Arrows as b -> Products as -> b Source #

currys :: (Products as -> b) -> Arrows as b Source #

Instances

Currying ([] *) b Source # 

Methods

uncurrys :: Arrows [*] b -> Products [*] -> b Source #

currys :: (Products [*] -> b) -> Arrows [*] b Source #

Currying ((:) * a2 as) b => Currying ((:) * a1 ((:) * a2 as)) b Source # 

Methods

uncurrys :: Arrows ((* ': a1) ((* ': a2) as)) b -> Products ((* ': a1) ((* ': a2) as)) -> b Source #

currys :: (Products ((* ': a1) ((* ': a2) as)) -> b) -> Arrows ((* ': a1) ((* ': a2) as)) b Source #

Currying ((:) * a ([] *)) b Source # 

Methods

uncurrys :: Arrows ((* ': a) [*]) b -> Products ((* ': a) [*]) -> b Source #

currys :: (Products ((* ': a) [*]) -> b) -> Arrows ((* ': a) [*]) b Source #

data Function :: * -> * -> * Source #

Instances

type Apply * (Function b * -> *) (Constant0 b *) a Source # 
type Apply * (Function b * -> *) (Constant0 b *) a = Constant1 b * a
type Apply k (Function [l] [l] -> *) (ConsMap0 k l f) a Source # 
type Apply k (Function [l] [l] -> *) (ConsMap0 k l f) a = ConsMap1 k l f a

data Constant0 :: Function a (Function b a -> *) -> * Source #

Instances

type Apply * (Function b * -> *) (Constant0 b *) a Source # 
type Apply * (Function b * -> *) (Constant0 b *) a = Constant1 b * a

data Constant1 :: * -> Function b a -> * Source #

Instances

type Apply k * (Constant1 k * a) b Source # 
type Apply k * (Constant1 k * a) b = a

type family Apply (t :: Function k l -> *) (u :: k) :: l Source #

Instances

type Apply k * (Constant1 k * a) b Source # 
type Apply k * (Constant1 k * a) b = a
type Apply * (Function b * -> *) (Constant0 b *) a Source # 
type Apply * (Function b * -> *) (Constant0 b *) a = Constant1 b * a
type Apply k (Function [l] [l] -> *) (ConsMap0 k l f) a Source # 
type Apply k (Function [l] [l] -> *) (ConsMap0 k l f) a = ConsMap1 k l f a
type Apply [a1] [a1] (ConsMap1 k a1 f a2) tl Source # 
type Apply [a1] [a1] (ConsMap1 k a1 f a2) tl = (:) a1 (Apply k a1 f a2) tl