{-# LANGUAGE CPP #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeOperators #-} #if __GLASGOW_HASKELL__ >= 704 {-# LANGUAGE Safe #-} #elif __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif #if __GLASGOW_HASKELL__ >= 706 {-# LANGUAGE PolyKinds #-} #endif module Data.Bifunctor.Functor ( (:->) , BifunctorFunctor(..) , BifunctorMonad(..) , biliftM , BifunctorComonad(..) , biliftW ) where -- | Using parametricity as an approximation of a natural transformation in two arguments. type (:->) p q = forall a b. p a b -> q a b infixr 0 :-> class BifunctorFunctor t where bifmap :: (p :-> q) -> t p :-> t q class BifunctorFunctor t => BifunctorMonad t where bireturn :: p :-> t p bibind :: (p :-> t q) -> t p :-> t q bibind f = bijoin . bifmap f bijoin :: t (t p) :-> t p bijoin = bibind id #if __GLASGOW_HASKELL__ >= 708 {-# MINIMAL bireturn, (bibind | bijoin) #-} #endif biliftM :: BifunctorMonad t => (p :-> q) -> t p :-> t q biliftM f = bibind (bireturn . f) {-# INLINE biliftM #-} class BifunctorFunctor t => BifunctorComonad t where biextract :: t p :-> p biextend :: (t p :-> q) -> t p :-> t q biextend f = bifmap f . biduplicate biduplicate :: t p :-> t (t p) biduplicate = biextend id #if __GLASGOW_HASKELL__ >= 708 {-# MINIMAL biextract, (biextend | biduplicate) #-} #endif biliftW :: BifunctorComonad t => (p :-> q) -> t p :-> t q biliftW f = biextend (f . biextract) {-# INLINE biliftW #-}