1{-# LANGUAGE CPP #-} 2{-# LANGUAGE RankNTypes #-} 3{-# LANGUAGE TypeOperators #-} 4 5#if __GLASGOW_HASKELL__ >= 704 6{-# LANGUAGE Safe #-} 7#elif __GLASGOW_HASKELL__ >= 702 8{-# LANGUAGE Trustworthy #-} 9#endif 10 11#if __GLASGOW_HASKELL__ >= 706 12{-# LANGUAGE PolyKinds #-} 13#endif 14 15module Data.Bifunctor.Functor 16 ( (:->) 17 , BifunctorFunctor(..) 18 , BifunctorMonad(..) 19 , biliftM 20 , BifunctorComonad(..) 21 , biliftW 22 ) where 23 24-- | Using parametricity as an approximation of a natural transformation in two arguments. 25type (:->) p q = forall a b. p a b -> q a b 26infixr 0 :-> 27 28class BifunctorFunctor t where 29 bifmap :: (p :-> q) -> t p :-> t q 30 31class BifunctorFunctor t => BifunctorMonad t where 32 bireturn :: p :-> t p 33 bibind :: (p :-> t q) -> t p :-> t q 34 bibind f = bijoin . bifmap f 35 bijoin :: t (t p) :-> t p 36 bijoin = bibind id 37#if __GLASGOW_HASKELL__ >= 708 38 {-# MINIMAL bireturn, (bibind | bijoin) #-} 39#endif 40 41biliftM :: BifunctorMonad t => (p :-> q) -> t p :-> t q 42biliftM f = bibind (bireturn . f) 43{-# INLINE biliftM #-} 44 45class BifunctorFunctor t => BifunctorComonad t where 46 biextract :: t p :-> p 47 biextend :: (t p :-> q) -> t p :-> t q 48 biextend f = bifmap f . biduplicate 49 biduplicate :: t p :-> t (t p) 50 biduplicate = biextend id 51#if __GLASGOW_HASKELL__ >= 708 52 {-# MINIMAL biextract, (biextend | biduplicate) #-} 53#endif 54 55biliftW :: BifunctorComonad t => (p :-> q) -> t p :-> t q 56biliftW f = biextend (f . biextract) 57{-# INLINE biliftW #-} 58