module Control.Functor.Combinators.Flip
( Flip(..)
, liftFlip
) where
import Control.Monad.Identity
import Control.Functor
import Control.Category.Hask
import Control.Category.Associative
import Control.Category.Monoidal
newtype Flip p a b = Flip { runFlip :: p b a }
liftFlip :: (p a b -> p c d) -> Flip p b a -> Flip p d c
liftFlip f = Flip . f . runFlip
instance PFunctor p Hask Hask => QFunctor (Flip p) Hask Hask where
second g = liftFlip (first g)
instance QFunctor p Hask Hask => PFunctor (Flip p) Hask Hask where
first f = liftFlip (second f)
instance Bifunctor p Hask Hask Hask => Bifunctor (Flip p) Hask Hask Hask where
bimap f g = liftFlip (bimap g f)
instance Braided Hask p => Braided Hask (Flip p) where
braid = liftFlip braid
instance Symmetric Hask p => Symmetric Hask (Flip p)
instance Bifunctor p Hask Hask Hask => Functor (Flip p a) where
fmap = bimap id
instance HasIdentity Hask p i => HasIdentity Hask (Flip p) i where
instance Associative Hask p => Coassociative Hask (Flip p) where
coassociate = Flip . second Flip . associate . first runFlip . runFlip
instance Coassociative Hask p => Associative Hask (Flip p) where
associate = Flip . first Flip . coassociate . second runFlip . runFlip
instance (Coassociative Hask p, Monoidal Hask p i) => Monoidal Hask (Flip p) i where
idl = idr . runFlip
idr = idl . runFlip
instance (Associative Hask p, Comonoidal Hask p i) => Comonoidal Hask (Flip p) i where
coidl = Flip . coidr
coidr = Flip . coidl