{-# LANGUAGE CPP #-} {-# LANGUAGE Rank2Types #-} {-# LANGUAGE TypeFamilies #-} #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif ----------------------------------------------------------------------------- -- | -- Copyright : (C) 2014 Edward Kmett -- License : BSD-style (see the file LICENSE) -- -- Maintainer : Edward Kmett -- Stability : provisional -- Portability : Rank2Types, TFs -- ---------------------------------------------------------------------------- module Data.Profunctor.Lift ( Lift(..) , decomposeLift ) where import Control.Category import Data.Profunctor.Unsafe import Data.Profunctor.Composition import Prelude hiding (id,(.)) -- | This represents the left Kan lift of a 'Profunctor' @q@ along a 'Profunctor' @p@ in a limited version of the 2-category of Profunctors where the only object is the category Hask, 1-morphisms are profunctors composed and compose with Profunctor composition, and 2-morphisms are just natural transformations. newtype Lift p q a b = Lift { runLift :: forall x. p b x -> q a x } instance (Profunctor p, Profunctor q) => Profunctor (Lift p q) where dimap ca bd f = Lift (lmap ca . runLift f . lmap bd) {-# INLINE dimap #-} lmap ca f = Lift (lmap ca . runLift f) {-# INLINE lmap #-} rmap bd f = Lift (runLift f . lmap bd) {-# INLINE rmap #-} bd #. f = Lift (\p -> runLift f (p .# bd)) {-# INLINE ( #. ) #-} f .# ca = Lift (\p -> runLift f p .# ca) {-# INLINE (.#) #-} instance Profunctor p => Functor (Lift p q a) where fmap bd f = Lift (runLift f . lmap bd) {-# INLINE fmap #-} -- | @'Lift' p p@ forms a 'Monad' in the 'Profunctor' 2-category, which is isomorphic to a Haskell 'Category' instance. instance p ~ q => Category (Lift p q) where id = Lift id {-# INLINE id #-} Lift f . Lift g = Lift (g . f) {-# INLINE (.) #-} -- | The 2-morphism that defines a left Kan lift. -- -- Note: When @p@ is right adjoint to @'Lift' p (->)@ then 'decomposeLift' is the 'counit' of the adjunction. decomposeLift :: Procompose (Lift p q) p a b -> q a b decomposeLift (Procompose (Lift pq) p) = pq p {-# INLINE decomposeLift #-}