{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DefaultSignatures #-}
module Symantic.Derive where
import Data.Function ((.))
import Data.Kind (Type)
type family Derived (repr :: Type -> Type) :: Type -> Type
class Derivable repr where
derive :: repr a -> Derived repr a
class LiftDerived repr where
liftDerived :: Derived repr a -> repr a
class LiftDerived1 repr where
liftDerived1 ::
(Derived repr a -> Derived repr b) ->
repr a -> repr b
liftDerived1 Derived repr a -> Derived repr b
f = Derived repr b -> repr b
forall (repr :: * -> *) a.
LiftDerived repr =>
Derived repr a -> repr a
liftDerived (Derived repr b -> repr b)
-> (repr a -> Derived repr b) -> repr a -> repr b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Derived repr a -> Derived repr b
f (Derived repr a -> Derived repr b)
-> (repr a -> Derived repr a) -> repr a -> Derived repr b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. repr a -> Derived repr a
forall (repr :: * -> *) a.
Derivable repr =>
repr a -> Derived repr a
derive
default liftDerived1 ::
LiftDerived repr => Derivable repr =>
(Derived repr a -> Derived repr b) ->
repr a -> repr b
class LiftDerived2 repr where
liftDerived2 ::
(Derived repr a -> Derived repr b -> Derived repr c) ->
repr a -> repr b -> repr c
liftDerived2 Derived repr a -> Derived repr b -> Derived repr c
f repr a
a repr b
b = Derived repr c -> repr c
forall (repr :: * -> *) a.
LiftDerived repr =>
Derived repr a -> repr a
liftDerived (Derived repr a -> Derived repr b -> Derived repr c
f (repr a -> Derived repr a
forall (repr :: * -> *) a.
Derivable repr =>
repr a -> Derived repr a
derive repr a
a) (repr b -> Derived repr b
forall (repr :: * -> *) a.
Derivable repr =>
repr a -> Derived repr a
derive repr b
b))
default liftDerived2 ::
LiftDerived repr => Derivable repr =>
(Derived repr a -> Derived repr b -> Derived repr c) ->
repr a -> repr b -> repr c
class LiftDerived3 repr where
liftDerived3 ::
(Derived repr a -> Derived repr b -> Derived repr c -> Derived repr d) ->
repr a -> repr b -> repr c -> repr d
liftDerived3 Derived repr a
-> Derived repr b -> Derived repr c -> Derived repr d
f repr a
a repr b
b repr c
c = Derived repr d -> repr d
forall (repr :: * -> *) a.
LiftDerived repr =>
Derived repr a -> repr a
liftDerived (Derived repr a
-> Derived repr b -> Derived repr c -> Derived repr d
f (repr a -> Derived repr a
forall (repr :: * -> *) a.
Derivable repr =>
repr a -> Derived repr a
derive repr a
a) (repr b -> Derived repr b
forall (repr :: * -> *) a.
Derivable repr =>
repr a -> Derived repr a
derive repr b
b) (repr c -> Derived repr c
forall (repr :: * -> *) a.
Derivable repr =>
repr a -> Derived repr a
derive repr c
c))
default liftDerived3 ::
LiftDerived repr => Derivable repr =>
(Derived repr a -> Derived repr b -> Derived repr c -> Derived repr d) ->
repr a -> repr b -> repr c -> repr d
class LiftDerived4 repr where
liftDerived4 ::
(Derived repr a -> Derived repr b -> Derived repr c -> Derived repr d -> Derived repr e) ->
repr a -> repr b -> repr c -> repr d -> repr e
liftDerived4 Derived repr a
-> Derived repr b
-> Derived repr c
-> Derived repr d
-> Derived repr e
f repr a
a repr b
b repr c
c repr d
d = Derived repr e -> repr e
forall (repr :: * -> *) a.
LiftDerived repr =>
Derived repr a -> repr a
liftDerived (Derived repr a
-> Derived repr b
-> Derived repr c
-> Derived repr d
-> Derived repr e
f (repr a -> Derived repr a
forall (repr :: * -> *) a.
Derivable repr =>
repr a -> Derived repr a
derive repr a
a) (repr b -> Derived repr b
forall (repr :: * -> *) a.
Derivable repr =>
repr a -> Derived repr a
derive repr b
b) (repr c -> Derived repr c
forall (repr :: * -> *) a.
Derivable repr =>
repr a -> Derived repr a
derive repr c
c) (repr d -> Derived repr d
forall (repr :: * -> *) a.
Derivable repr =>
repr a -> Derived repr a
derive repr d
d))
default liftDerived4 ::
LiftDerived repr => Derivable repr =>
(Derived repr a -> Derived repr b -> Derived repr c -> Derived repr d -> Derived repr e) ->
repr a -> repr b -> repr c -> repr d -> repr e
type FromDerived sym repr = ( LiftDerived repr, sym (Derived repr) )
type FromDerived1 sym repr = ( LiftDerived1 repr, sym (Derived repr) )
type FromDerived2 sym repr = ( LiftDerived2 repr, sym (Derived repr) )
type FromDerived3 sym repr = ( LiftDerived3 repr, sym (Derived repr) )
type FromDerived4 sym repr = ( LiftDerived4 repr, sym (Derived repr) )