packages feed

pandora-0.4.5: Pandora/Paradigm/Primary/Transformer/Reverse.hs

{-# LANGUAGE UndecidableInstances #-}

module Pandora.Paradigm.Primary.Transformer.Reverse where

import Pandora.Pattern.Semigroupoid ((.))
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.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 ((/|\)))
import Pandora.Paradigm.Primary.Transformer.Backwards (Backwards (Backwards))
import Pandora.Paradigm.Controlflow.Effect.Interpreted (Interpreted (Primary, run, unite))

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 Traversable t (->) (->) => Traversable (Reverse t) (->) (->) where
	f <<- Reverse x = Reverse -<$>- run (Backwards . f <<- x)

instance Distributive t (->) (->) => Distributive (Reverse t) (->) (->) where
	f -<< x = Reverse $ run . f -<< x

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
	unite = Reverse

instance Liftable Reverse where
	lift = Reverse

instance Lowerable Reverse where
	lower = run

instance Hoistable Reverse where
	f /|\ Reverse x = Reverse # f x