module Pandora.Paradigm.Primary.Transformer.Reverse where import Pandora.Pattern.Category ((.), ($)) import Pandora.Pattern.Functor.Covariant (Covariant ((<$>))) import Pandora.Pattern.Functor.Contravariant (Contravariant ((>$<))) import Pandora.Pattern.Functor.Extractable (Extractable (extract)) import Pandora.Pattern.Functor.Pointable (Pointable (point)) import Pandora.Pattern.Functor.Applicative (Applicative ((<*>))) import Pandora.Pattern.Functor.Traversable (Traversable ((->>))) import Pandora.Pattern.Functor.Distributive (Distributive ((>>-))) import Pandora.Pattern.Transformer.Liftable (Liftable (lift)) import Pandora.Pattern.Transformer.Lowerable (Lowerable (lower)) import Pandora.Pattern.Transformer.Hoistable (Hoistable (hoist)) import Pandora.Paradigm.Primary.Transformer.Backwards (Backwards (Backwards)) import Pandora.Paradigm.Controlflow.Effect.Interpreted (Interpreted (Primary, run)) newtype Reverse t a = Reverse (t a) instance Covariant t => Covariant (Reverse t) where f <$> Reverse x = Reverse $ f <$> x instance Pointable t => Pointable (Reverse t) where point = Reverse . point instance Extractable t => Extractable (Reverse t) where extract (Reverse x) = extract x instance Applicative t => Applicative (Reverse t) where Reverse f <*> Reverse x = Reverse (f <*> x) instance Traversable t => Traversable (Reverse t) where Reverse x ->> f = Reverse <$> run (x ->> Backwards . f) instance Distributive t => Distributive (Reverse t) where x >>- f = Reverse $ x >>- run . f instance Contravariant t => Contravariant (Reverse t) where f >$< Reverse x = Reverse $ f >$< x instance Interpreted (Reverse t) where type Primary (Reverse t) a = t a run ~(Reverse x) = x instance Liftable Reverse where lift = Reverse instance Lowerable Reverse where lower = run instance Hoistable Reverse where hoist f (Reverse x) = Reverse $ f x