module Data.Functor.Composition.TTT (TTT (..)) where import "morphisms" Control.Morphism ((.), ($)) import Control.Functor.Covariant (Covariant ((<$>), comap)) import Control.Functor.Covariant.Extractable (Extractable (extract)) import Control.Functor.Covariant.Exclusive (Exclusive (exclusive)) import Control.Functor.Covariant.Pointable (Pointable (point)) import Control.Functor.Covariant.Alternative (Alternative ((<+>))) import Control.Functor.Covariant.Applicative (Applicative ((<*>), apply)) import Control.Functor.Covariant.Composition.Adjoint (Adjoint (phi, psi)) import Control.Functor.Contravariant (Contravariant ((>$<), contramap)) import Control.Variance (Variant (Co, Contra), (:.:)) newtype TTT ct cu cv cw t u v w a = TTT { ttt :: (t :.: u :.: v :.: w) a } instance (Covariant t, Covariant u, Covariant v, Covariant w) => Covariant (TTT Co Co Co Co t u v w) where f <$> TTT x = TTT $ (comap . comap . comap . comap) f x instance (Covariant t, Covariant u, Covariant v, Contravariant w) => Contravariant (TTT Co Co Co Contra t u v w) where f >$< TTT x = TTT $ (comap . comap . comap) (contramap f) x instance (Covariant t, Covariant u, Contravariant v, Covariant w) => Contravariant (TTT Co Co Contra Co t u v w) where f >$< TTT x = TTT $ (comap . comap) (contramap (comap f)) x instance (Covariant t, Contravariant u, Covariant v, Covariant w) => Contravariant (TTT Co Contra Co Co t u v w) where f >$< TTT x = TTT $ (contramap (comap (comap f))) <$> x instance (Contravariant t, Covariant u, Covariant v, Covariant w) => Contravariant (TTT Contra Co Co Co t u v w) where f >$< TTT x = TTT $ comap (comap (comap f)) >$< x instance (Contravariant t, Contravariant u, Covariant v, Covariant w) => Covariant (TTT Contra Contra Co Co t u v w) where f <$> TTT x = TTT $ (contramap . contramap . comap . comap $ f) x instance (Covariant t, Contravariant u, Contravariant v, Covariant w) => Covariant (TTT Co Contra Contra Co t u v w) where f <$> TTT x = TTT $ (comap . contramap . contramap . comap $ f) x instance (Covariant t, Covariant u, Contravariant v, Contravariant w) => Covariant (TTT Co Co Contra Contra t u v w) where f <$> TTT x = TTT $ (comap . comap) (contramap . contramap $ f) x instance (Covariant t, Contravariant u, Covariant v, Contravariant w) => Covariant (TTT Co Contra Co Contra t u v w) where f <$> TTT x = TTT $ (comap . contramap . comap . contramap $ f) x instance (Contravariant t, Covariant u, Contravariant v, Covariant w) => Covariant (TTT Contra Co Contra Co t u v w) where f <$> TTT x = TTT $ (contramap . comap . contramap . comap $ f) x instance (Contravariant t, Covariant u, Covariant v, Contravariant w) => Covariant (TTT Contra Co Co Contra t u v w) where f <$> TTT x = TTT $ (contramap . comap . comap . contramap $ f) x instance (Contravariant t, Contravariant u, Contravariant v, Covariant w) => Contravariant (TTT Contra Contra Contra Co t u v w) where f >$< TTT x = TTT $ (contramap . contramap . contramap . comap) f x instance (Covariant t, Contravariant u, Contravariant v, Contravariant w) => Contravariant (TTT Co Contra Contra Contra t u v w) where f >$< TTT x = TTT $ (comap . contramap . contramap . contramap) f x instance (Contravariant t, Covariant u, Contravariant v, Contravariant w) => Contravariant (TTT Contra Co Contra Contra t u v w) where f >$< TTT x = TTT $ (contramap . comap . contramap . contramap) f x instance (Contravariant t, Contravariant u, Covariant v, Contravariant w) => Contravariant (TTT Contra Contra Co Contra t u v w) where f >$< TTT x = TTT $ (contramap . contramap . comap . contramap) f x instance (Contravariant t, Contravariant u, Contravariant v, Contravariant w) => Covariant (TTT Contra Contra Contra Contra t u v w) where f <$> TTT x = TTT $ (contramap . contramap . contramap . contramap) f x instance (Applicative t, Applicative u, Applicative v, Applicative w) => Applicative (TTT Co Co Co Co t u v w) where TTT f <*> TTT x = TTT $ (comap apply . (comap . comap) apply . (comap . comap . comap) apply $ f) <*> x instance (Alternative t, Covariant u, Covariant v, Covariant w) => Alternative (TTT Co Co Co Co t u v w) where TTT x <+> TTT y = TTT $ x <+> y instance (Exclusive t, Covariant u, Covariant v, Covariant w) => Exclusive (TTT Co Co Co Co t u v w) where exclusive = TTT exclusive instance (Pointable t, Pointable u, Pointable v, Pointable w) => Pointable (TTT Co Co Co Co t u v w) where point = TTT . point . point . point . point instance (Extractable t, Extractable u, Extractable v, Extractable w) => Extractable (TTT Co Co Co Co t u v w) where extract = extract . extract . extract . extract . ttt type Adjunctive t u = (Extractable t, Pointable t, Extractable u, Pointable u, Adjoint t u) instance (Adjunctive t u, Adjunctive t' u', Adjunctive t'' u'', Adjunctive t''' u''') => Adjoint (TTT Co Co Co Co t t' t'' t''') (TTT Co Co Co Co u u' u'' u''') where phi f = point . f . point psi f = extract . extract . comap f