module Data.Functor.Arrow.Opposite (Opposite (..), type (<--)) where

import "morphisms" Control.Morphism ((.), ($))

import Control.Functor.Contravariant (Contravariant ((>$<)))
import Control.Functor.Polyvariant.Orpvariant (Orpvariant (orpmap))

newtype Opposite a b = Opposite { opposite :: b -> a }

type (<--) = Opposite

instance Contravariant (Opposite a) where
        f >$< g = Opposite (opposite g . f)

instance Orpvariant Opposite where
        orpmap f g (Opposite h) = Opposite $ f . h . g