-- |
-- Module      : Data.HFunctor.Route
-- Copyright   : (c) Justin Le 2019
-- License     : BSD3
--
-- Maintainer  : justin@jle.im
-- Stability   : experimental
-- Portability : non-portable
--
-- This module contains the useful combinators 'Pre' and 'Post', which
-- enhances a functor with a "route" to and from the outside world; even if
-- the functor itself is existentially closed in a functor combinator, the
-- route will provide line to the outside world for extraction or
-- injection.
--
-- See 'Pre' and 'Post' for more information.
--
-- @since 0.3.4.0
module Data.HFunctor.Route (
  -- * Routing Combinators
  -- ** Contravariant
    Pre(..)
  , interpretPre, getPre, retractPre
  , injectPre, mapPre
  , preDivisible, preDivise, preContravariant
  -- ** Covariant
  , Post(..)
  , interpretPost, getPost, retractPost
  , injectPost, mapPost
  , postPlus, postAlt, postFunctor
  -- * Wrapped Invariant
  -- ** Contravariant
  , PreT(..)
  , preDivisibleT, preDiviseT, preContravariantT
  -- ** Covariant
  , PostT(..)
  , postPlusT, postAltT, postFunctorT
  ) where

import           Control.Natural
import           Data.Functor.Invariant.Inplicative
import           Data.Functor.Invariant.Internative
import           Data.Functor.Bind
import           Data.Functor.Contravariant
import           Data.Functor.Contravariant.Conclude
import           Data.Functor.Contravariant.Decide
import           Data.Functor.Contravariant.Divise
import           Data.Functor.Contravariant.Divisible
import           Data.Functor.Invariant
import           Data.Functor.Plus
import           Data.HFunctor
import           Data.HFunctor.HTraversable
import           Data.HFunctor.Interpret
import           Data.Profunctor
import           Data.Void

-- | A useful helper type to use with a covariant functor combinator that
-- allows you to tag along contravariant access to all @f@s inside the
-- combinator.
--
-- Maybe most usefully, it can be used with 'Ap'.  Remember that @'Ap' f a@
-- is a collection of @f x@s, with each x existentially wrapped.  Now, for
-- a @'Ap' (Pre a f) a@, it will be a collection of @f x@ and @a -> x@s:
-- not only each individual part, but a way to "select" that individual
-- part from the overal @a@.
--
-- So, you can imagine @'Ap' ('Pre' a f) b@ as a collection of @f x@ that
-- consumes @a@ and produces @b@.
--
-- When @a@ and @b@ are the same, @'Ap' ('Pre' a f) a@ is like the free
-- invariant sequencer.  That is, in a sense, @'Ap' ('Pre' a f) a@ contains
-- both contravariant and covariant sequences side-by-side, /consuming/
-- @a@s and also /producing/ @a@s.
--
-- You can build up these values with 'injectPre', and then use whatever
-- typeclasses your @t@ normally supports to build it up, like
-- 'Applicative' (for 'Ap').  You can then interpret it into both its
-- contravariant and covariant contexts:
--
-- @
-- -- interpret the covariant part
-- runCovariant :: 'Applicative' g => (f ~> g) -> Ap (Pre a f) a -> g a
-- runCovariant f = interpret (f . getPre)
--
-- -- interpret the contravariant part
-- runContravariant :: 'Divisible' g => (f ~> g) -> Ap (Pre a f) a -> g a
-- runContravariant = preDivisible
-- @
--
-- The 'PreT' type wraps up @'Ap' ('Pre' a f) a@ into a type @'PreT' 'Ap'
-- f a@, with nice instances/helpers.
--
-- An example of a usage of this in the real world is the /unjson/
-- library's record type constructor, to implement bidrectional
-- serializers for product types.
data Pre  a f b = (a -> b) :>$<: f b
  deriving forall a b. a -> Pre a f b -> Pre a f a
forall a b. (a -> b) -> Pre a f a -> Pre a f b
forall a (f :: * -> *) a b.
Functor f =>
a -> Pre a f b -> Pre a f a
forall a (f :: * -> *) a b.
Functor f =>
(a -> b) -> Pre a f a -> Pre a f b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> Pre a f b -> Pre a f a
$c<$ :: forall a (f :: * -> *) a b.
Functor f =>
a -> Pre a f b -> Pre a f a
fmap :: forall a b. (a -> b) -> Pre a f a -> Pre a f b
$cfmap :: forall a (f :: * -> *) a b.
Functor f =>
(a -> b) -> Pre a f a -> Pre a f b
Functor


-- | A useful helper type to use with a contravariant functor combinator that
-- allows you to tag along covariant access to all @f@s inside the
-- combinator.
--
-- Maybe most usefully, it can be used with 'Dec'.  Remember that @'Dec' f a@
-- is a collection of @f x@s, with each x existentially wrapped.  Now, for
-- a @'Dec' (Post a f) a@, it will be a collection of @f x@ and @x -> a@s:
-- not only each individual part, but a way to "re-embed" that individual
-- part into overal @a@.
--
-- So, you can imagine @'Dec' ('Post' a f) b@ as a collection of @f x@ that
-- consumes @b@ and produces @a@.
--
-- When @a@ and @b@ are the same, @'Dec' ('Post' a f) a@ is like the free
-- invariant sequencer.  That is, in a sense, @'Dec' ('Post' a f) a@ contains
-- both contravariant and covariant sequences side-by-side, /consuming/
-- @a@s and also /producing/ @a@s.
--
-- You can build up these values with 'injectPre', and then use whatever
-- typeclasses your @t@ normally supports to build it up, like
-- 'Conclude' (for 'Div').  You can then interpret it into both its
-- contravariant and covariant contexts:
--
-- @
-- -- interpret the covariant part
-- runCovariant :: 'Plus' g => (f ~> g) -> Div (Post a f) a -> g a
-- runCovariant f = interpret (f . getPost)
--
-- -- interpret the contravariant part
-- runContravariant :: 'Conclude' g => (f ~> g) -> Div (Post a f) a -> g a
-- runContravariant = preDivisible
-- @
--
-- The 'PostT' type wraps up @'Dec' ('Post' a f) a@ into a type @'PostT'
-- 'Dec'
-- f a@, with nice instances/helpers.
--
-- An example of a usage of this in the real world is a possible
-- implementation of the /unjson/ library's sum type constructor, to
-- implement bidrectional serializers for sum types.
data Post a f b = (b -> a) :<$>: f b

instance Contravariant f => Contravariant (Post a f) where
    contramap :: forall a' a. (a' -> a) -> Post a f a -> Post a f a'
contramap a' -> a
f (a -> a
g :<$>: f a
x) = a -> a
g forall b c a. (b -> c) -> (a -> b) -> a -> c
. a' -> a
f forall a (f :: * -> *) b. (b -> a) -> f b -> Post a f b
:<$>: forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap a' -> a
f f a
x

infixl 4 :>$<:
infixl 4 :<$>:

-- | Turn the covariant functor combinator @t@ into an 'Invariant'
-- functor combinator; if @t f a@ "produces" @a@s, then @'PreT' t f a@ will
-- both consume and produce @a@s.
--
-- You can run this normally as if it were a @t f a@ by using 'interpret';
-- however, you can also interpret into covariant contexts with
-- 'preDivisibleT', 'preDiviseT', and 'preContravariantT'.
--
-- A useful way to use this type is to use normal methods of the underlying
-- @t@ to assemble a final @t@, then using the 'PreT' constructor to wrap
-- it all up.
--
-- @
-- data MyType = MyType
--      { mtInt    :: Int
--      , mtBool   :: Bool
--      , mtString :: String
--      }
--
-- myThing :: PreT Ap MyFunctor MyType
-- myThing = PreT $ MyType
--     <$> injectPre mtInt    (mfInt    :: MyFunctor Int   )
--     <*> injectPre mtBool   (mfBool   :: MyFunctor Bool  )
--     <*> injectPre mtString (mfString :: MyFunctor STring)
-- @
--
-- See 'Pre' for more information.
newtype PreT t f a = PreT { forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PreT t f a -> t (Pre a f) a
unPreT :: t (Pre a f) a }

instance (HFunctor t, forall x. Functor (t (Pre x f))) => Invariant (PreT t f) where
    invmap :: forall a b. (a -> b) -> (b -> a) -> PreT t f a -> PreT t f b
invmap a -> b
f b -> a
g = forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
t (Pre a f) a -> PreT t f a
PreT
               forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {k1} (t :: (k -> *) -> k1 -> *) (f :: k -> *)
       (g :: k -> *).
HFunctor t =>
(f ~> g) -> t f ~> t g
hmap (forall c a (f :: * -> *) b. (c -> a) -> Pre a f b -> Pre c f b
mapPre b -> a
g)
               forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f
               forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PreT t f a -> t (Pre a f) a
unPreT

instance HFunctor t => HFunctor (PreT t) where
    hmap :: forall (f :: * -> *) (g :: * -> *).
(f ~> g) -> PreT t f ~> PreT t g
hmap f ~> g
f = forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
t (Pre a f) a -> PreT t f a
PreT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {k1} (t :: (k -> *) -> k1 -> *) (f :: k -> *)
       (g :: k -> *).
HFunctor t =>
(f ~> g) -> t f ~> t g
hmap (forall {k} {k1} (t :: (k -> *) -> k1 -> *) (f :: k -> *)
       (g :: k -> *).
HFunctor t =>
(f ~> g) -> t f ~> t g
hmap f ~> g
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PreT t f a -> t (Pre a f) a
unPreT

instance Inject t => Inject (PreT t) where
    inject :: forall (f :: * -> *). f ~> PreT t f
inject = forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
t (Pre a f) a -> PreT t f a
PreT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (t :: (k -> *) -> k -> *) (f :: k -> *).
Inject t =>
f ~> t f
inject forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. a -> a
id forall a (f :: * -> *) b. (a -> b) -> f b -> Pre a f b
:>$<:)

instance HTraversable t => HTraversable (PreT t) where
    htraverse :: forall (h :: * -> *) (f :: * -> *) (g :: * -> *) a.
Applicative h =>
(forall x. f x -> h (g x)) -> PreT t f a -> h (PreT t g a)
htraverse forall x. f x -> h (g x)
f = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
t (Pre a f) a -> PreT t f a
PreT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {k1} (t :: (k -> *) -> k1 -> *) (h :: * -> *)
       (f :: k -> *) (g :: k -> *) (a :: k1).
(HTraversable t, Applicative h) =>
(forall (x :: k). f x -> h (g x)) -> t f a -> h (t g a)
htraverse (forall {k} {k1} (t :: (k -> *) -> k1 -> *) (h :: * -> *)
       (f :: k -> *) (g :: k -> *) (a :: k1).
(HTraversable t, Applicative h) =>
(forall (x :: k). f x -> h (g x)) -> t f a -> h (t g a)
htraverse forall x. f x -> h (g x)
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PreT t f a -> t (Pre a f) a
unPreT

instance Interpret t f => Interpret (PreT t) f where
    interpret :: forall (g :: * -> *). (g ~> f) -> PreT t g ~> f
interpret g ~> f
f = forall {k} (t :: (k -> *) -> k -> *) (f :: k -> *) (g :: k -> *).
Interpret t f =>
(g ~> f) -> t g ~> f
interpret g ~> f
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {k1} (t :: (k -> *) -> k1 -> *) (f :: k -> *)
       (g :: k -> *).
HFunctor t =>
(f ~> g) -> t f ~> t g
hmap forall a (f :: * -> *) b. Pre a f b -> f b
getPre forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PreT t f a -> t (Pre a f) a
unPreT

-- | Turn the contravariant functor combinator @t@ into an 'Invariant'
-- functor combinator; if @t f a@ "consumes" @a@s, then @'PostT' t f a@ will
-- both consume and produce @a@s.
--
-- You can run this normally as if it were a @t f a@ by using 'interpret';
-- however, you can also interpret into covariant contexts with
-- 'postPlusT', 'postAltT', and 'postFunctorT'.
--
-- A useful way to use this type is to use normal methods of the underlying
-- @t@ to assemble a final @t@, then using the 'PreT' constructor to wrap
-- it all up.
--
-- @
-- myThing :: PostT Dec MyFunctor (Either Int Bool)
-- myThing = PostT $ decided $
--     (injectPost Left  (mfInt  :: MyFunctor Int ))
--     (injectPost Right (mfBool :: MyFunctor Bool))
-- @
--
-- See 'Post' for more information.
newtype PostT t f a = PostT { forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PostT t f a -> t (Post a f) a
unPostT :: t (Post a f) a }

instance (HFunctor t, forall x. Contravariant (t (Post x f))) => Invariant (PostT t f) where
    invmap :: forall a b. (a -> b) -> (b -> a) -> PostT t f a -> PostT t f b
invmap a -> b
f b -> a
g = forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
t (Post a f) a -> PostT t f a
PostT
               forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {k1} (t :: (k -> *) -> k1 -> *) (f :: k -> *)
       (g :: k -> *).
HFunctor t =>
(f ~> g) -> t f ~> t g
hmap (forall a c (f :: * -> *) b. (a -> c) -> Post a f b -> Post c f b
mapPost a -> b
f)
               forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap b -> a
g
               forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PostT t f a -> t (Post a f) a
unPostT

-- | @since 0.3.4.2
instance HFunctor t => HFunctor (PostT t) where
    hmap :: forall (f :: * -> *) (g :: * -> *).
(f ~> g) -> PostT t f ~> PostT t g
hmap f ~> g
f = forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
t (Post a f) a -> PostT t f a
PostT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {k1} (t :: (k -> *) -> k1 -> *) (f :: k -> *)
       (g :: k -> *).
HFunctor t =>
(f ~> g) -> t f ~> t g
hmap (forall {k} {k1} (t :: (k -> *) -> k1 -> *) (f :: k -> *)
       (g :: k -> *).
HFunctor t =>
(f ~> g) -> t f ~> t g
hmap f ~> g
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PostT t f a -> t (Post a f) a
unPostT

-- | @since 0.3.4.2
instance Inject t => Inject (PostT t) where
    inject :: forall (f :: * -> *). f ~> PostT t f
inject = forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
t (Post a f) a -> PostT t f a
PostT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (t :: (k -> *) -> k -> *) (f :: k -> *).
Inject t =>
f ~> t f
inject forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. a -> a
id forall a (f :: * -> *) b. (b -> a) -> f b -> Post a f b
:<$>:)

instance HTraversable t => HTraversable (PostT t) where
    htraverse :: forall (h :: * -> *) (f :: * -> *) (g :: * -> *) a.
Applicative h =>
(forall x. f x -> h (g x)) -> PostT t f a -> h (PostT t g a)
htraverse forall x. f x -> h (g x)
f = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
t (Post a f) a -> PostT t f a
PostT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {k1} (t :: (k -> *) -> k1 -> *) (h :: * -> *)
       (f :: k -> *) (g :: k -> *) (a :: k1).
(HTraversable t, Applicative h) =>
(forall (x :: k). f x -> h (g x)) -> t f a -> h (t g a)
htraverse (forall {k} {k1} (t :: (k -> *) -> k1 -> *) (h :: * -> *)
       (f :: k -> *) (g :: k -> *) (a :: k1).
(HTraversable t, Applicative h) =>
(forall (x :: k). f x -> h (g x)) -> t f a -> h (t g a)
htraverse forall x. f x -> h (g x)
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PostT t f a -> t (Post a f) a
unPostT

-- | @since 0.3.4.2
instance Interpret t f => Interpret (PostT t) f where
    interpret :: forall (g :: * -> *). (g ~> f) -> PostT t g ~> f
interpret g ~> f
f = forall {k} (t :: (k -> *) -> k -> *) (f :: k -> *) (g :: k -> *).
Interpret t f =>
(g ~> f) -> t g ~> f
interpret g ~> f
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {k1} (t :: (k -> *) -> k1 -> *) (f :: k -> *)
       (g :: k -> *).
HFunctor t =>
(f ~> g) -> t f ~> t g
hmap forall a (f :: * -> *) b. Post a f b -> f b
getPost forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PostT t f a -> t (Post a f) a
unPostT

-- | Run a @'PreT' t@ into a contravariant 'Divisible' context.  To run it
-- in @t@s normal covariant context, use 'interpret'.
--
-- This will work for types where there are a possibly-empty collection of
-- @f@s, like:
--
-- @
-- preDivisibleT :: Divisible g => (f ~> g) -> PreT 'Ap'    f ~> g
-- preDivisibleT :: Divisible g => (f ~> g) -> PreT 'ListF' f ~> g
-- @
preDivisibleT
    :: (forall m. Monoid m => Interpret t (AltConst m), Divisible g)
    => (f ~> g)
    -> PreT t f ~> g
preDivisibleT :: forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *).
(forall m. Monoid m => Interpret t (AltConst m), Divisible g) =>
(f ~> g) -> PreT t f ~> g
preDivisibleT f ~> g
f = forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *) a b.
(forall m. Monoid m => Interpret t (AltConst m), Divisible g) =>
(f ~> g) -> t (Pre a f) b -> g a
preDivisible f ~> g
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PreT t f a -> t (Pre a f) a
unPreT

-- | Run a @'PreT' t@ into a contravariant 'Divise' context.  To run it in
-- @t@s normal covariant context, use 'interpret'.
--
-- This will work for types where there is a non-empty collection of
-- @f@s, like:
--
-- @
-- preDiviseT :: Divise g => (f ~> g) -> PreT 'Ap1'       f ~> g
-- preDiviseT :: Divise g => (f ~> g) -> PreT 'NonEmptyF' f ~> g
-- @
preDiviseT
    :: (forall m. Semigroup m => Interpret t (AltConst m), Divise g)
    => (f ~> g)
    -> PreT t f ~> g
preDiviseT :: forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *).
(forall m. Semigroup m => Interpret t (AltConst m), Divise g) =>
(f ~> g) -> PreT t f ~> g
preDiviseT f ~> g
f = forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *) a b.
(forall m. Semigroup m => Interpret t (AltConst m), Divise g) =>
(f ~> g) -> t (Pre a f) b -> g a
preDivise f ~> g
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PreT t f a -> t (Pre a f) a
unPreT

-- | Run a @'PreT' t@ into a 'Contravariant'.  To run it in
-- @t@s normal covariant context, use 'interpret'.
--
-- This will work for types where there is exactly one @f@ inside:
--
-- @
-- preContravariantT :: Contravariant g => (f ~> g) -> PreT 'Step'     f ~> g
-- preContravariantT :: Contravariant g => (f ~> g) -> PreT 'Coyoneda' f ~> g
-- @
preContravariantT
    :: (forall m. Interpret t (AltConst m), Contravariant g)
    => (f ~> g)
    -> PreT t f ~> g
preContravariantT :: forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *).
(forall m. Interpret t (AltConst m), Contravariant g) =>
(f ~> g) -> PreT t f ~> g
preContravariantT f ~> g
f = forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *) a b.
(forall m. Interpret t (AltConst m), Contravariant g) =>
(f ~> g) -> t (Pre a f) b -> g a
preContravariant f ~> g
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PreT t f a -> t (Pre a f) a
unPreT

-- | Run a "pre-routed" @t@ into a contravariant 'Divisible' context.  To
-- run it in @t@s normal covariant context, use 'interpret' with 'getPre'.
--
-- This will work for types where there are a possibly-empty collection of
-- @f@s, like:
--
-- @
-- preDivisible :: Divisible g => (f ~> g) -> 'Ap'    ('Pre' a f) b -> g a
-- preDivisible :: Divisible g => (f ~> g) -> 'ListF' ('Pre' a f) b -> g a
-- @
preDivisible
    :: (forall m. Monoid m => Interpret t (AltConst m), Divisible g)
    => (f ~> g)
    -> t (Pre a f) b
    -> g a
preDivisible :: forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *) a b.
(forall m. Monoid m => Interpret t (AltConst m), Divisible g) =>
(f ~> g) -> t (Pre a f) b -> g a
preDivisible f ~> g
f = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (forall (f :: * -> *) a b c.
Divisible f =>
(a -> (b, c)) -> f b -> f c -> f a
divide (\a
x -> (a
x,a
x))) forall (f :: * -> *) a. Divisible f => f a
conquer
               forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (t :: (k -> *) -> k -> *) (f :: k -> *) b (a :: k).
(forall m. Monoid m => Interpret t (AltConst m)) =>
(forall (x :: k). f x -> b) -> t f a -> [b]
icollect (forall (g :: * -> *) (f :: * -> *) a b.
Contravariant g =>
(f ~> g) -> Pre a f b -> g a
interpretPre f ~> g
f)

-- | Run a "pre-routed" @t@ into a contravariant 'Divise' context.  To
-- run it in @t@s normal covariant context, use 'interpret' with 'getPre'.
--
-- This will work for types where there are is a non-empty collection of
-- @f@s, like:
--
-- @
-- preDivise :: Divise g => (f ~> g) -> 'Ap1'       ('Pre' a f) b -> g a
-- preDivise :: Divise g => (f ~> g) -> 'NonEmptyF' ('Pre' a f) b -> g a
-- @
preDivise
    :: (forall m. Semigroup m => Interpret t (AltConst m), Divise g)
    => (f ~> g)
    -> t (Pre a f) b
    -> g a
preDivise :: forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *) a b.
(forall m. Semigroup m => Interpret t (AltConst m), Divise g) =>
(f ~> g) -> t (Pre a f) b -> g a
preDivise f ~> g
f = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 forall (f :: * -> *) a. Divise f => f a -> f a -> f a
(<:>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (t :: (k -> *) -> k -> *) (f :: k -> *) b (a :: k).
(forall m. Semigroup m => Interpret t (AltConst m)) =>
(forall (x :: k). f x -> b) -> t f a -> NonEmpty b
icollect1 (forall (g :: * -> *) (f :: * -> *) a b.
Contravariant g =>
(f ~> g) -> Pre a f b -> g a
interpretPre f ~> g
f)

-- | Run a "pre-routed" @t@ into a 'Contravariant'.  To run it in @t@s
-- normal covariant context, use 'interpret' with 'getPre'.
--
-- This will work for types where there is exactly one @f@ inside:
--
-- @
-- preContravariant :: Contravariant g => (f ~> g) -> 'Step'     ('Pre' a f) b -> g a
-- preContravariant :: Contravariant g => (f ~> g) -> 'Coyoneda' ('Pre' a f) b -> g a
-- @
preContravariant
    :: (forall m. Interpret t (AltConst m), Contravariant g)
    => (f ~> g)
    -> t (Pre a f) b
    -> g a
preContravariant :: forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *) a b.
(forall m. Interpret t (AltConst m), Contravariant g) =>
(f ~> g) -> t (Pre a f) b -> g a
preContravariant f ~> g
f = forall {k} (t :: (k -> *) -> k -> *) b (f :: k -> *) (a :: k).
Interpret t (AltConst b) =>
(forall (x :: k). f x -> b) -> t f a -> b
iget (forall (g :: * -> *) (f :: * -> *) a b.
Contravariant g =>
(f ~> g) -> Pre a f b -> g a
interpretPre f ~> g
f)

-- | Run a @'PostT' t@ into a covariant 'Plus' context.  To run it
-- in @t@s normal contravariant context, use 'interpret'.
--
-- This will work for types where there are a possibly-empty collection of
-- @f@s, like:
--
-- @
-- postPlusT :: Plus g => (f ~> g) -> PreT 'Dec' f ~> g
-- postPlusT :: Plus g => (f ~> g) -> PreT 'Div' f ~> g
-- @
postPlusT
    :: (forall m. Monoid m => Interpret t (AltConst m), Plus g)
    => (f ~> g)
    -> PostT t f ~> g
postPlusT :: forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *).
(forall m. Monoid m => Interpret t (AltConst m), Plus g) =>
(f ~> g) -> PostT t f ~> g
postPlusT f ~> g
f = forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *) a b.
(forall m. Monoid m => Interpret t (AltConst m), Plus g) =>
(f ~> g) -> t (Post a f) b -> g a
postPlus f ~> g
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PostT t f a -> t (Post a f) a
unPostT

-- | Run a @'PostT' t@ into a covariant 'Alt' context.  To run it
-- in @t@s normal contravariant context, use 'interpret'.
--
-- This will work for types where there is a non-empty collection of
-- @f@s, like:
--
-- @
-- postAltT :: Alt g => (f ~> g) -> PreT 'Dec1' f ~> g
-- postAltT :: Alt g => (f ~> g) -> PreT 'Div1' f ~> g
-- @
postAltT
    :: (forall m. Semigroup m => Interpret t (AltConst m), Alt g)
    => (f ~> g)
    -> PostT t f ~> g
postAltT :: forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *).
(forall m. Semigroup m => Interpret t (AltConst m), Alt g) =>
(f ~> g) -> PostT t f ~> g
postAltT f ~> g
f = forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *) a b.
(forall m. Semigroup m => Interpret t (AltConst m), Alt g) =>
(f ~> g) -> t (Post a f) b -> g a
postAlt f ~> g
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PostT t f a -> t (Post a f) a
unPostT

-- | Run a @'PostT' t@ into a covariant 'Functor' context.  To run it
-- in @t@s normal contravariant context, use 'interpret'.
--
-- This will work for types where there is exactly one @f@ inside:
--
-- @
-- postFunctorT :: Functor g => (f ~> g) -> PreT 'Step' f ~> g
-- postFunctorT :: Functor g => (f ~> g) -> PreT 'CCY.Coyoneda' f ~> g
-- @
postFunctorT
    :: (forall m. Interpret t (AltConst m), Functor g)
    => (f ~> g)
    -> PostT t f ~> g
postFunctorT :: forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *).
(forall m. Interpret t (AltConst m), Functor g) =>
(f ~> g) -> PostT t f ~> g
postFunctorT f ~> g
f = forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *) a b.
(forall m. Interpret t (AltConst m), Functor g) =>
(f ~> g) -> t (Post a f) b -> g a
postFunctor f ~> g
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (f :: * -> *) a.
PostT t f a -> t (Post a f) a
unPostT

-- | Run a "post-routed" @t@ into a covariant 'Plus' context.  To run it
-- in @t@s normal contravariant context, use 'interpret'.
--
-- This will work for types where there are a possibly-empty collection of
-- @f@s, like:
--
-- @
-- postPlus :: Plus g => (f ~> g) -> 'Dec' (Post a f) b -> g a
-- postPlus :: Plus g => (f ~> g) -> 'Div' (Post a f) b -> g a
-- @
postPlus
    :: (forall m. Monoid m => Interpret t (AltConst m), Plus g)
    => (f ~> g)
    -> t (Post a f) b
    -> g a
postPlus :: forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *) a b.
(forall m. Monoid m => Interpret t (AltConst m), Plus g) =>
(f ~> g) -> t (Post a f) b -> g a
postPlus f ~> g
f = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall (f :: * -> *) a. Alt f => f a -> f a -> f a
(<!>) forall (f :: * -> *) a. Plus f => f a
zero forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (t :: (k -> *) -> k -> *) (f :: k -> *) b (a :: k).
(forall m. Monoid m => Interpret t (AltConst m)) =>
(forall (x :: k). f x -> b) -> t f a -> [b]
icollect (forall (g :: * -> *) (f :: * -> *) a b.
Functor g =>
(f ~> g) -> Post a f b -> g a
interpretPost f ~> g
f)

-- | Run a "post-routed" @t@ into a covariant 'Alt' context.  To run it
-- in @t@s normal contravariant context, use 'interpret'.
--
-- This will work for types where there are is a non-empty collection of
-- @f@s, like:
--
-- @
-- postAlt :: Alt g => (f ~> g) -> 'Dec1' (Post a f) b -> g a
-- postAlt :: Alt g => (f ~> g) -> 'Div1' (Post a f) b -> g a
-- @
postAlt
    :: (forall m. Semigroup m => Interpret t (AltConst m), Alt g)
    => (f ~> g)
    -> t (Post a f) b
    -> g a
postAlt :: forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *) a b.
(forall m. Semigroup m => Interpret t (AltConst m), Alt g) =>
(f ~> g) -> t (Post a f) b -> g a
postAlt f ~> g
f = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 forall (f :: * -> *) a. Alt f => f a -> f a -> f a
(<!>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (t :: (k -> *) -> k -> *) (f :: k -> *) b (a :: k).
(forall m. Semigroup m => Interpret t (AltConst m)) =>
(forall (x :: k). f x -> b) -> t f a -> NonEmpty b
icollect1 (forall (g :: * -> *) (f :: * -> *) a b.
Functor g =>
(f ~> g) -> Post a f b -> g a
interpretPost f ~> g
f)

-- | Run a "post-routed" @t@ into a covariant 'Functor' context.  To run it
-- in @t@s normal contravariant context, use 'interpret'.
--
-- This will work for types where there is exactly one @f@ inside:
--
-- @
-- postFunctor :: Functor g => (f ~> g) -> 'Step'         (Post a f) b -> g a
-- postFunctor :: Functor g => (f ~> g) -> 'CCY.Coyoneda' (Post a f) b -> g a
-- @
postFunctor
    :: (forall m. Interpret t (AltConst m), Functor g)
    => (f ~> g)
    -> t (Post a f) b
    -> g a
postFunctor :: forall (t :: (* -> *) -> * -> *) (g :: * -> *) (f :: * -> *) a b.
(forall m. Interpret t (AltConst m), Functor g) =>
(f ~> g) -> t (Post a f) b -> g a
postFunctor f ~> g
f = forall {k} (t :: (k -> *) -> k -> *) b (f :: k -> *) (a :: k).
Interpret t (AltConst b) =>
(forall (x :: k). f x -> b) -> t f a -> b
iget (forall (g :: * -> *) (f :: * -> *) a b.
Functor g =>
(f ~> g) -> Post a f b -> g a
interpretPost f ~> g
f)

-- | Contravariantly retract the @f@ out of a 'Pre', applying the
-- pre-routing function.  Not usually that useful because 'Pre' is meant to
-- be used with covariant 'Functor's.
retractPre :: Contravariant f => Pre a f b -> f a
retractPre :: forall (f :: * -> *) a b. Contravariant f => Pre a f b -> f a
retractPre (a -> b
f :>$<: f b
x) = forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap a -> b
f f b
x

-- | Interpret a 'Pre' into a contravariant context, applying the
-- pre-routing function.
interpretPre :: Contravariant g => (f ~> g) -> Pre a f b -> g a
interpretPre :: forall (g :: * -> *) (f :: * -> *) a b.
Contravariant g =>
(f ~> g) -> Pre a f b -> g a
interpretPre f ~> g
f (a -> b
g :>$<: f b
x) = forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap a -> b
g (f ~> g
f f b
x)

-- | Drop the pre-routing function and just give the original wrapped
-- value.
getPre :: Pre a f b -> f b
getPre :: forall a (f :: * -> *) b. Pre a f b -> f b
getPre (a -> b
_ :>$<: f b
x) = f b
x

-- | Pre-compose on the pre-routing function.
mapPre :: (c -> a) -> Pre a f b -> Pre c f b
mapPre :: forall c a (f :: * -> *) b. (c -> a) -> Pre a f b -> Pre c f b
mapPre c -> a
f (a -> b
g :>$<: f b
x) = a -> b
g forall b c a. (b -> c) -> (a -> b) -> a -> c
. c -> a
f forall a (f :: * -> *) b. (a -> b) -> f b -> Pre a f b
:>$<: f b
x

-- | Like 'inject', but allowing you to provide a pre-routing function.
injectPre :: Inject t => (a -> b) -> f b -> t (Pre a f) b
injectPre :: forall (t :: (* -> *) -> * -> *) a b (f :: * -> *).
Inject t =>
(a -> b) -> f b -> t (Pre a f) b
injectPre a -> b
f f b
x = forall {k} (t :: (k -> *) -> k -> *) (f :: k -> *).
Inject t =>
f ~> t f
inject (a -> b
f forall a (f :: * -> *) b. (a -> b) -> f b -> Pre a f b
:>$<: f b
x)

-- | Covariantly retract the @f@ out of a 'Post', applying the
-- post-routing function.  Not usually that useful because 'Post' is meant to
-- be used with contravariant 'Functor's.
retractPost :: Functor f => Post a f b -> f a
retractPost :: forall (f :: * -> *) a b. Functor f => Post a f b -> f a
retractPost (b -> a
f :<$>: f b
x) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> a
f f b
x

-- | Interpret a 'Post' into a covariant context, applying the
-- post-routing function.
interpretPost :: Functor g => (f ~> g) -> Post a f b -> g a
interpretPost :: forall (g :: * -> *) (f :: * -> *) a b.
Functor g =>
(f ~> g) -> Post a f b -> g a
interpretPost f ~> g
f (b -> a
g :<$>: f b
x) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> a
g (f ~> g
f f b
x)

-- | Drop the post-routing function and just give the original wrapped
-- value.
getPost :: Post a f b -> f b
getPost :: forall a (f :: * -> *) b. Post a f b -> f b
getPost (b -> a
_ :<$>: f b
x) = f b
x

-- | Post-compose on the post-routing function.
mapPost :: (a -> c) -> Post a f b -> Post c f b
mapPost :: forall a c (f :: * -> *) b. (a -> c) -> Post a f b -> Post c f b
mapPost a -> c
f (b -> a
g :<$>: f b
x) = a -> c
f  forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> a
g forall a (f :: * -> *) b. (b -> a) -> f b -> Post a f b
:<$>: f b
x

-- | Like 'inject', but allowing you to provide a post-routing function.
injectPost :: Inject t => (b -> a) -> f b -> t (Post a f) b
injectPost :: forall (t :: (* -> *) -> * -> *) b a (f :: * -> *).
Inject t =>
(b -> a) -> f b -> t (Post a f) b
injectPost b -> a
f f b
x = forall {k} (t :: (k -> *) -> k -> *) (f :: k -> *).
Inject t =>
f ~> t f
inject (b -> a
f forall a (f :: * -> *) b. (b -> a) -> f b -> Post a f b
:<$>: f b
x)

instance Functor f => Invariant (Post a f) where
    invmap :: forall a b. (a -> b) -> (b -> a) -> Post a f a -> Post a f b
invmap a -> b
f b -> a
g (a -> a
h :<$>: f a
x) = a -> a
h forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> a
g forall a (f :: * -> *) b. (b -> a) -> f b -> Post a f b
:<$>: forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f f a
x

instance Contravariant f => Invariant (Pre a f) where
    invmap :: forall a b. (a -> b) -> (b -> a) -> Pre a f a -> Pre a f b
invmap a -> b
f b -> a
g (a -> a
h :>$<: f a
x) = a -> b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
h forall a (f :: * -> *) b. (a -> b) -> f b -> Pre a f b
:>$<: forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap b -> a
g f a
x

instance HFunctor (Post a) where
    hmap :: forall (f :: * -> *) (g :: * -> *).
(f ~> g) -> Post a f ~> Post a g
hmap f ~> g
g (x -> a
f :<$>: f x
x) = x -> a
f forall a (f :: * -> *) b. (b -> a) -> f b -> Post a f b
:<$>: f ~> g
g f x
x

instance HFunctor (Pre a) where
    hmap :: forall (f :: * -> *) (g :: * -> *). (f ~> g) -> Pre a f ~> Pre a g
hmap f ~> g
g (a -> x
f :>$<: f x
x) = a -> x
f forall a (f :: * -> *) b. (a -> b) -> f b -> Pre a f b
:>$<: f ~> g
g f x
x

instance HTraversable (Post a) where
    htraverse :: forall (h :: * -> *) (f :: * -> *) (g :: * -> *) a.
Applicative h =>
(forall x. f x -> h (g x)) -> Post a f a -> h (Post a g a)
htraverse forall x. f x -> h (g x)
g (a -> a
f :<$>: f a
x) = (a -> a
f forall a (f :: * -> *) b. (b -> a) -> f b -> Post a f b
:<$>:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall x. f x -> h (g x)
g f a
x

instance HTraversable (Pre a) where
    htraverse :: forall (h :: * -> *) (f :: * -> *) (g :: * -> *) a.
Applicative h =>
(forall x. f x -> h (g x)) -> Pre a f a -> h (Pre a g a)
htraverse forall x. f x -> h (g x)
g (a -> a
f :>$<: f a
x) = (a -> a
f forall a (f :: * -> *) b. (a -> b) -> f b -> Pre a f b
:>$<:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall x. f x -> h (g x)
g f a
x

instance Monoid a => Inject (Post a) where
    inject :: forall (f :: * -> *). f ~> Post a f
inject f x
x = forall a b. a -> b -> a
const forall a. Monoid a => a
mempty forall a (f :: * -> *) b. (b -> a) -> f b -> Post a f b
:<$>: f x
x

instance Monoid a => HBind (Post a) where
    hjoin :: forall (f :: * -> *). Post a (Post a f) ~> Post a f
hjoin (x -> a
f :<$>: (x -> a
g :<$>: f x
x)) = (x -> a
f forall a. Semigroup a => a -> a -> a
<> x -> a
g) forall a (f :: * -> *) b. (b -> a) -> f b -> Post a f b
:<$>: f x
x

instance Monoid a => Interpret (Post a) f where
    retract :: Post a f ~> f
retract (x -> a
_ :<$>: f x
x) = f x
x

-- | This instance is over-contrained (@a@ only needs to be uninhabited),
-- but there is no commonly used "uninhabited" typeclass
instance (a ~ Void) => Inject (Pre a) where
    inject :: forall (f :: * -> *). f ~> Pre a f
inject f x
x = forall a. Void -> a
absurd forall a (f :: * -> *) b. (a -> b) -> f b -> Pre a f b
:>$<: f x
x

-- | This instance is over-contrained (@a@ only needs to be uninhabited),
-- but there is no commonly used "uninhabited" typeclass
instance (a ~ Void) => HBind (Pre a) where
    hjoin :: forall (f :: * -> *). Pre a (Pre a f) ~> Pre a f
hjoin (a -> x
_ :>$<: (a -> x
_ :>$<: f x
x)) = forall a. Void -> a
absurd forall a (f :: * -> *) b. (a -> b) -> f b -> Pre a f b
:>$<: f x
x

instance (a ~ Void) => Interpret (Pre a) f where
    retract :: Pre a f ~> f
retract (a -> x
_ :>$<: f x
x) = f x
x

-- | If @t@ is a covariant functor combinator, then you applying it to
-- @'Pre' a f@ gives you a profunctor.
newtype ProPre t f a b = ProPre { forall {k} (t :: (* -> *) -> k -> *) (f :: * -> *) a (b :: k).
ProPre t f a b -> t (Pre a f) b
unProPre :: t (Pre a f) b }

instance (HFunctor t, forall x. Functor (t (Pre x f))) => Profunctor (ProPre t f) where
    dimap :: forall a b c d.
(a -> b) -> (c -> d) -> ProPre t f b c -> ProPre t f a d
dimap a -> b
f c -> d
g = forall {k} (t :: (* -> *) -> k -> *) (f :: * -> *) a (b :: k).
t (Pre a f) b -> ProPre t f a b
ProPre
              forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {k1} (t :: (k -> *) -> k1 -> *) (f :: k -> *)
       (g :: k -> *).
HFunctor t =>
(f ~> g) -> t f ~> t g
hmap (forall c a (f :: * -> *) b. (c -> a) -> Pre a f b -> Pre c f b
mapPre a -> b
f)
              forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> d
g
              forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (t :: (* -> *) -> k -> *) (f :: * -> *) a (b :: k).
ProPre t f a b -> t (Pre a f) b
unProPre


-- | @since 0.3.4.1
deriving instance Functor (t (Pre a f)) => Functor (ProPre t f a)
-- | @since 0.3.4.1
deriving instance Apply (t (Pre a f)) => Apply (ProPre t f a)
-- | @since 0.3.4.1
deriving instance Applicative (t (Pre a f)) => Applicative (ProPre t f a)
-- | @since 0.3.4.1
instance Bind (t (Pre a f)) => Bind (ProPre t f a) where
    ProPre t (Pre a f) a
x >>- :: forall a b.
ProPre t f a a -> (a -> ProPre t f a b) -> ProPre t f a b
>>- a -> ProPre t f a b
f = forall {k} (t :: (* -> *) -> k -> *) (f :: * -> *) a (b :: k).
t (Pre a f) b -> ProPre t f a b
ProPre forall a b. (a -> b) -> a -> b
$ t (Pre a f) a
x forall (m :: * -> *) a b. Bind m => m a -> (a -> m b) -> m b
>>- (forall {k} (t :: (* -> *) -> k -> *) (f :: * -> *) a (b :: k).
ProPre t f a b -> t (Pre a f) b
unProPre forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ProPre t f a b
f)
-- | @since 0.3.4.1
deriving instance Monad (t (Pre a f)) => Monad (ProPre t f a)
-- | @since 0.3.4.1
deriving instance Contravariant (t (Pre a f)) => Contravariant (ProPre t f a)
-- | @since 0.3.4.1
deriving instance Divisible (t (Pre a f)) => Divisible (ProPre t f a)
-- | @since 0.3.4.1
deriving instance Divise (t (Pre a f)) => Divise (ProPre t f a)
-- | @since 0.3.4.1
deriving instance Decide (t (Pre a f)) => Decide (ProPre t f a)
-- | @since 0.3.4.1
deriving instance Conclude (t (Pre a f)) => Conclude (ProPre t f a)
-- | @since 0.3.4.1
deriving instance Decidable (t (Pre a f)) => Decidable (ProPre t f a)
-- | @since 0.3.4.1
deriving instance Plus (t (Pre a f)) => Plus (ProPre t f a)
-- | @since 0.3.4.1
instance Alt (t (Pre a f)) => Alt (ProPre t f a) where
    ProPre t (Pre a f) a
x <!> :: forall a. ProPre t f a a -> ProPre t f a a -> ProPre t f a a
<!> ProPre t (Pre a f) a
y = forall {k} (t :: (* -> *) -> k -> *) (f :: * -> *) a (b :: k).
t (Pre a f) b -> ProPre t f a b
ProPre (t (Pre a f) a
x forall (f :: * -> *) a. Alt f => f a -> f a -> f a
<!> t (Pre a f) a
y)
-- | @since 0.3.4.1
deriving instance Invariant (t (Pre a f)) => Invariant (ProPre t f a)
-- | @since 0.4.0.0.0
deriving instance Inply (t (Pre a f)) => Inply (ProPre t f a)
-- | @since 0.4.0.0.0
deriving instance Inplicative (t (Pre a f)) => Inplicative (ProPre t f a)
-- | @since 0.4.0.0.0
deriving instance Inalt (t (Pre a f)) => Inalt (ProPre t f a)
-- | @since 0.4.0.0.0
deriving instance Inplus (t (Pre a f)) => Inplus (ProPre t f a)
-- | @since 0.4.0.0.0
deriving instance Internative (t (Pre a f)) => Internative (ProPre t f a)
-- | @since 0.3.4.1
deriving instance Semigroup (t (Pre a f) b) => Semigroup (ProPre t f a b)
-- | @since 0.3.4.1
deriving instance Monoid (t (Pre a f) b) => Monoid (ProPre t f a b)
-- | @since 0.3.4.1
deriving instance Show (t (Pre a f) b) => Show (ProPre t f a b)
-- | @since 0.3.4.1
deriving instance Eq (t (Pre a f) b) => Eq (ProPre t f a b)
-- | @since 0.3.4.1
deriving instance Ord (t (Pre a f) b) => Ord (ProPre t f a b)



-- | If @t@ is a contravariant functor combinator, then you applying it to
-- @'Post' a f@ gives you a profunctor.
newtype ProPost t f a b = ProPost { forall {k} (t :: (* -> *) -> k -> *) (f :: * -> *) (a :: k) b.
ProPost t f a b -> t (Post b f) a
unProPost :: t (Post b f) a }

instance (HFunctor t, forall x. Contravariant (t (Post x f))) => Profunctor (ProPost t f) where
    dimap :: forall a b c d.
(a -> b) -> (c -> d) -> ProPost t f b c -> ProPost t f a d
dimap a -> b
f c -> d
g = forall {k} (t :: (* -> *) -> k -> *) (f :: * -> *) (a :: k) b.
t (Post b f) a -> ProPost t f a b
ProPost
              forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {k1} (t :: (k -> *) -> k1 -> *) (f :: k -> *)
       (g :: k -> *).
HFunctor t =>
(f ~> g) -> t f ~> t g
hmap (forall a c (f :: * -> *) b. (a -> c) -> Post a f b -> Post c f b
mapPost c -> d
g)
              forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap a -> b
f
              forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (t :: (* -> *) -> k -> *) (f :: * -> *) (a :: k) b.
ProPost t f a b -> t (Post b f) a
unProPost

-- | @since 0.3.4.1
instance (HFunctor t, Contravariant (t (Post a f))) => Functor (ProPost t f a) where
    fmap :: forall a b. (a -> b) -> ProPost t f a a -> ProPost t f a b
fmap a -> b
f = forall {k} (t :: (* -> *) -> k -> *) (f :: * -> *) (a :: k) b.
t (Post b f) a -> ProPost t f a b
ProPost
           forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {k1} (t :: (k -> *) -> k1 -> *) (f :: k -> *)
       (g :: k -> *).
HFunctor t =>
(f ~> g) -> t f ~> t g
hmap (forall a c (f :: * -> *) b. (a -> c) -> Post a f b -> Post c f b
mapPost a -> b
f)
           forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (t :: (* -> *) -> k -> *) (f :: * -> *) (a :: k) b.
ProPost t f a b -> t (Post b f) a
unProPost
-- | @since 0.3.4.1
instance (HFunctor t, Contravariant (t (Post a f))) => Invariant (ProPost t f a) where
    invmap :: forall a b.
(a -> b) -> (b -> a) -> ProPost t f a a -> ProPost t f a b
invmap a -> b
f b -> a
_ = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f