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