{-# LANGUAGE CPP #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeFamilies #-}
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
------------------------------------------------------------------------------- |-- Copyright : (C) 2013 Edward Kmett and Dan Doel-- License : BSD-style (see the file LICENSE)---- Maintainer : Edward Kmett <ekmett@gmail.com>-- Stability : provisional-- Portability : Rank2Types, TFs------------------------------------------------------------------------------
module Data.Profunctor.Rift
( Rift(..)
, decomposeRift
, precomposeRift
) where
import Control.Category
import Data.Profunctor.Unsafe
import Data.Profunctor.Composition
import Prelude hiding (id,(.))
-- | This represents the right 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 Riftpqab = Rift { runRift :: forall x. pxa -> qxb }
-- Ran f g a = forall b. (a -> f b) -> g b
instance (Profunctor p, Profunctor q) =>Profunctor (Riftpq) where
dimapcabdf = Rift (rmapbd.runRiftf.rmapca)
{-# INLINE dimap #-}lmapcaf = Rift (runRiftf.rmapca)
{-# INLINE lmap #-}rmapbdf = Rift (rmapbd.runRiftf)
{-# INLINE rmap #-}bd#.f = Rift (\p -> bd#.runRiftfp)
{-# INLINE ( #. ) #-}f.#ca = Rift (\p -> runRiftf (ca#.p))
{-# INLINE (.#) #-}
instance Profunctor q =>Functor (Riftpqa) where
fmapbdf = Rift (rmapbd.runRiftf)
{-# INLINE fmap #-}-- | @'Rift' p p@ forms a 'Monad' in the 'Profunctor' 2-category, which is isomorphic to a Haskell 'Category' instance.
instance p ~ q => Category (Riftpq) where
id = Riftid{-# INLINE id #-}Riftf.Riftg = Rift (f.g)
{-# INLINE (.) #-}-- | The 2-morphism that defines a right Kan lift.---- Note: When @q@ is left adjoint to @'Rift' q (->)@ then 'decomposeRift' is the 'counit' of the adjunction.decomposeRift :: Procomposeq (Riftqp) ab -> pabdecomposeRift (Procomposeq (Riftqp)) = qpq{-# INLINE decomposeRift #-}precomposeRift :: Profunctor q =>Procompose (Riftp(->)) qab -> RiftpqabprecomposeRift (Procomposepfp) = Rift (\pxa -> runRiftpfpxa`lmap`p)
{-# INLINE precomposeRift #-}