module Pandora.Paradigm.Controlflow.Joint.Transformer (Transformer (..), (:>) (..)) where import Pandora.Core.Morphism ((.)) import Pandora.Core.Transformation (type (~>)) import Pandora.Paradigm.Controlflow.Joint.Interpreted (Interpreted (Primary, unwrap)) import Pandora.Pattern.Functor.Covariant (Covariant ((<$>))) import Pandora.Pattern.Functor.Pointable (Pointable (point)) import Pandora.Pattern.Functor.Extractable (Extractable (extract)) import Pandora.Pattern.Functor.Applicative (Applicative ((<*>))) import Pandora.Pattern.Functor.Alternative (Alternative ((<+>))) import Pandora.Pattern.Functor.Distributive (Distributive ((>>-))) import Pandora.Pattern.Functor.Traversable (Traversable ((->>))) import Pandora.Pattern.Functor.Bindable (Bindable ((>>=))) import Pandora.Pattern.Functor.Extendable (Extendable ((=>>))) import Pandora.Pattern.Functor.Divariant (($)) class Interpreted t => Transformer t where {-# MINIMAL lay, wrap #-} type Schema (t :: * -> *) (u :: * -> *) = (r :: * -> *) | r -> t u lay :: Covariant u => u ~> t :> u wrap :: Pointable u => t ~> t :> u infixr 3 :> newtype (:>) t u a = T { trans :: Schema t u a } instance Covariant (Schema t u) => Covariant (t :> u) where f <$> T x = T $ f <$> x instance Pointable (Schema t u) => Pointable (t :> u) where point = T . point instance Extractable (Schema t u) => Extractable (t :> u) where extract = extract . trans instance Applicative (Schema t u) => Applicative (t :> u) where T f <*> T x = T $ f <*> x instance Alternative (Schema t u) => Alternative (t :> u) where T x <+> T y = T $ x <+> y instance Traversable (Schema t u) => Traversable (t :> u) where T x ->> f = T <$> x ->> f instance Distributive (Schema t u) => Distributive (t :> u) where x >>- f = T $ x >>- trans . f instance Bindable (Schema t u) => Bindable (t :> u) where T x >>= f = T $ x >>= trans . f instance Extendable (Schema t u) => Extendable (t :> u) where T x =>> f = T $ x =>> f . T instance (Interpreted (Schema t u), Transformer t) => Interpreted (t :> u) where type Primary (t :> u) a = Primary (Schema t u) a unwrap (T x) = unwrap x