module Data.Bifunctor.Flip
( Flip(..)
) where
import Control.Applicative
import Data.Biapplicative
import Data.Bifunctor.Apply
import Data.Bifoldable
import Data.Bitraversable
import Data.Foldable
import Data.Monoid
import Data.Semigroup.Bifoldable
import Data.Semigroup.Bitraversable
import Data.Traversable
newtype Flip p a b = Flip { runFlip :: p b a }
deriving (Eq,Ord,Show,Read)
instance Bifunctor p => Bifunctor (Flip p) where
first f = Flip . second f . runFlip
second f = Flip . first f . runFlip
bimap f g = Flip . bimap g f . runFlip
instance Bifunctor p => Functor (Flip p a) where
fmap f = Flip . first f . runFlip
instance Biapplicative p => Biapplicative (Flip p) where
bipure a b = Flip (bipure b a)
Flip fg <<*>> Flip xy = Flip (fg <<*>> xy)
instance Biapply p => Biapply (Flip p) where
Flip fg <<.>> Flip xy = Flip (fg <<.>> xy)
instance Bifoldable p => Bifoldable (Flip p) where
bifoldMap f g = bifoldMap g f . runFlip
instance Bifoldable p => Foldable (Flip p a) where
foldMap f = bifoldMap f (const mempty) . runFlip
instance Bitraversable p => Bitraversable (Flip p) where
bitraverse f g = fmap Flip . bitraverse g f . runFlip
instance Bitraversable p => Traversable (Flip p a) where
traverse f = fmap Flip . bitraverse f pure . runFlip
instance Bifoldable1 p => Bifoldable1 (Flip p) where
bifoldMap1 f g = bifoldMap1 g f . runFlip
instance Bitraversable1 p => Bitraversable1 (Flip p) where
bitraverse1 f g = fmap Flip . bitraverse1 g f . runFlip