{-# LANGUAGE FlexibleContexts #-}

module Profunctor.Monad.Lifts where

import qualified Control.Category as Cat
import Control.Arrow (Arrow(..))
import Profunctor.Monad.Cofunctor

-- |
--
-- @
-- 'lmap' i ('lifts' p j)
-- =
-- 'lifts' ('lmap' i p) (i 'Cat.>>>' j)
-- @
--
-- @
-- 'lifts' p i '<*>' 'lifts' q j
-- =
-- 'lifts' (p '<*>' q) (i '&&&' j 'Cat.>>>' 'uncurry' ('$'))
-- @
class Cofunctor p => Lifts p where
  lifts :: p x a -> First p x a -> p x a

liftsArr
  :: (Lifts p, Arrow (First p))
  => p x a -> (x -> a) -> p x a
liftsArr :: p x a -> (x -> a) -> p x a
liftsArr p x a
p x -> a
f = p x a
p p x a -> First p x a -> p x a
forall (p :: * -> * -> *) x a.
Lifts p =>
p x a -> First p x a -> p x a
`lifts` (x -> a) -> First p x a
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr x -> a
f

liftsId
  :: Lifts p => p a a -> p a a
liftsId :: p a a -> p a a
liftsId p a a
p = p a a
p p a a -> First p a a -> p a a
forall (p :: * -> * -> *) x a.
Lifts p =>
p x a -> First p x a -> p x a
`lifts` First p a a
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
Cat.id