module Symantic.Base.Composable where
import Data.Function ((.))
class Composable repr where
default (<.>) :: Transformable repr => Composable (UnTrans repr) =>
repr a b -> repr b c -> repr a c
(<.>) :: repr a b -> repr b c -> repr a c
(<.>) = trans2 (<.>)
infixr 4 <.>
class Voidable repr where
default void :: Transformable repr => Voidable (UnTrans repr) =>
a -> repr (a -> b) k -> repr b k
void :: a -> repr (a -> b) k -> repr b k
void a = trans1 (void a)
class Transformable repr where
type UnTrans repr :: * -> * -> *
noTrans :: UnTrans repr a b -> repr a b
unTrans :: repr a b -> UnTrans repr a b
trans1 :: (UnTrans repr a b -> UnTrans repr c d) -> repr a b -> repr c d
trans1 f = noTrans . f . unTrans
trans2 :: (UnTrans repr a b -> UnTrans repr c d -> UnTrans repr e f) -> repr a b -> repr c d -> repr e f
trans2 f x y = noTrans (f (unTrans x) (unTrans y))
newtype IdentityTrans repr a k
= IdentityTrans
{ unIdentityTrans :: repr a k }
instance Transformable (IdentityTrans repr) where
type UnTrans (IdentityTrans repr) = repr
noTrans = IdentityTrans
unTrans = unIdentityTrans
class Dimapable repr where
default dimap :: Transformable repr => Dimapable (UnTrans repr) =>
(a->b) -> (b->a) -> repr (a->k) k -> repr (b->k) k
dimap :: (a->b) -> (b->a) -> repr (a->k) k -> repr (b->k) k
dimap a2b b2a = trans1 (dimap a2b b2a)