{-# LANGUAGE DerivingVia #-}

module Data.HFunctor.Internal (
    HFunctor(..)
  , HBifunctor(..)
  , WrappedHBifunctor(..)
  , sumSum, prodProd
  , generalize, absorb
  , NDL, ndlSingleton, fromNDL
  ) where

import           Control.Applicative.Backwards
import           Control.Applicative.Free
import           Control.Applicative.Lift
import           Control.Applicative.ListF
import           Control.Applicative.Step
import           Control.Comonad.Trans.Env
import           Control.Monad.Freer.Church
import           Control.Monad.Trans.Compose
import           Control.Monad.Trans.Identity
import           Control.Monad.Trans.Maybe
import           Control.Monad.Trans.Reader
import           Control.Natural
import           Control.Natural.IsoF
import           Data.Bifunctor
import           Data.Bifunctor.Joker
import           Data.Coerce
import           Data.Foldable
import           Data.Functor.Bind
import           Data.Functor.Contravariant.Night    (Night(..))
import           Data.Functor.Coyoneda
import           Data.Functor.Day                    (Day(..))
import           Data.Functor.Identity
import           Data.Functor.Product
import           Data.Functor.Reverse
import           Data.Functor.Sum
import           Data.Functor.These
import           Data.Functor.Yoneda
import           Data.Kind
import           Data.List.NonEmpty                  (NonEmpty(..))
import           Data.Proxy
import           Data.Tagged
import           Data.Vinyl.CoRec
import           Data.Vinyl.Core                     (Rec)
import           Data.Vinyl.Recursive
import           GHC.Generics
import qualified Control.Alternative.Free            as Alt
import qualified Control.Applicative.Free.Fast       as FAF
import qualified Control.Applicative.Free.Final      as FA
import qualified Control.Monad.Free.Church           as MC
import qualified Data.Functor.Contravariant.Coyoneda as CCY
import qualified Data.Functor.Contravariant.Day      as CD
import qualified Data.Functor.Contravariant.Night    as N
import qualified Data.Functor.Day                    as D
import qualified Data.SOP                            as SOP
import qualified Data.SOP.NP                         as SOP
import qualified Data.SOP.NS                         as SOP

-- | An 'HFunctor' can be thought of a unary "functor transformer" ---
-- a basic functor combinator.  It takes a functor as input and returns
-- a functor as output.
--
-- It "enhances" a functor with extra structure (sort of like how a monad
-- transformer enhances a 'Monad' with extra structure).
--
-- As a uniform inteface, we can "swap the underlying functor" (also
-- sometimes called "hoisting").  This is what 'hmap' does: it lets us swap
-- out the @f@ in a @t f@ for a @t g@.
--
-- For example, the free monad 'Free' takes a 'Functor' and returns a new
-- 'Functor'.  In the process, it provides a monadic structure over @f@.
-- 'hmap' lets us turn a @'Free' f@ into a @'Free' g@: a monad built over
-- @f@ can be turned into a monad built over @g@.
--
-- For the ability to move in and out of the enhanced functor, see
-- 'Data.HFunctor.Inject' and 'Data.HFunctor.Interpret.Interpret'.
--
-- This class is similar to 'Control.Monad.Morph.MFunctor' from
-- "Control.Monad.Morph", but instances must work without a 'Monad' constraint.
--
-- This class is also found in the /hschema/ library with the same name.
class HFunctor t where
    -- | If we can turn an @f@ into a @g@, then we can turn a @t f@ into
    -- a @t g@.
    --
    -- It must be the case that
    --
    -- @
    -- 'hmap' 'id' == id
    -- @
    --
    -- Essentially, @t f@ adds some "extra structure" to @f@.  'hmap'
    -- must swap out the functor, /without affecting the added structure/.
    --
    -- For example, @'ListF' f a@ is essentially a list of @f a@s.  If we
    -- 'hmap' to swap out the @f a@s for @g a@s, then we must ensure that
    -- the "added structure" (here, the number of items in the list, and
    -- the ordering of those items) remains the same.  So, 'hmap' must
    -- preserve the number of items in the list, and must maintain the
    -- ordering.
    --
    -- The law @'hmap' 'id' == id@ is a way of formalizing this property.
    hmap :: f ~> g -> t f ~> t g

    {-# MINIMAL hmap #-}

-- | A 'HBifunctor' is like an 'HFunctor', but it enhances /two/ different
-- functors instead of just one.
--
-- Usually, it enhaces them "together" in some sort of combining way.
--
-- This typeclass provides a uniform instance for "swapping out" or
-- "hoisting" the enhanced functors.   We can hoist the first one with
-- 'hleft', the second one with 'hright', or both at the same time with
-- 'hbimap'.
--
-- For example, the @f :*: g@ type gives us "both @f@ and @g@":
--
-- @
-- data (f ':*:' g) a = f a :*: g a
-- @
--
-- It combines both @f@ and @g@ into a unified structure --- here, it does
-- it by providing both @f@ and @g@.
--
-- The single law is:
--
-- @
-- 'hbimap' 'id' id == id
-- @
--
-- This ensures that 'hleft', 'hright', and 'hbimap' do not affect the
-- structure that @t@ adds on top of the underlying functors.
class HBifunctor (t :: (k -> Type) -> (k -> Type) -> k -> Type) where
    -- | Swap out the first transformed functor.
    hleft  :: f ~> j -> t f g ~> t j g
    hleft = ((f ~> j) -> (g ~> g) -> t f g ~> t j g
forall k (t :: (k -> *) -> (k -> *) -> k -> *) (f :: k -> *)
       (j :: k -> *) (g :: k -> *) (l :: k -> *).
HBifunctor t =>
(f ~> j) -> (g ~> l) -> t f g ~> t j l
`hbimap` g ~> g
forall a. a -> a
id)

    -- | Swap out the second transformed functor.
    hright :: g ~> l -> t f g ~> t f l
    hright = (f ~> f) -> (g ~> l) -> t f g ~> t f l
forall k (t :: (k -> *) -> (k -> *) -> k -> *) (f :: k -> *)
       (j :: k -> *) (g :: k -> *) (l :: k -> *).
HBifunctor t =>
(f ~> j) -> (g ~> l) -> t f g ~> t j l
hbimap f ~> f
forall a. a -> a
id

    -- | Swap out both transformed functors at the same time.
    hbimap :: f ~> j -> g ~> l -> t f g ~> t j l
    hbimap f :: f ~> j
f g :: g ~> l
g = (f ~> j) -> t f l ~> t j l
forall k (t :: (k -> *) -> (k -> *) -> k -> *) (f :: k -> *)
       (j :: k -> *) (g :: k -> *).
HBifunctor t =>
(f ~> j) -> t f g ~> t j g
hleft f ~> j
f (t f l x -> t j l x) -> (t f g x -> t f l x) -> t f g x -> t j l x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (g ~> l) -> t f g ~> t f l
forall k (t :: (k -> *) -> (k -> *) -> k -> *) (g :: k -> *)
       (l :: k -> *) (f :: k -> *).
HBifunctor t =>
(g ~> l) -> t f g ~> t f l
hright g ~> l
g

    {-# MINIMAL hleft, hright | hbimap #-}

-- | Useful newtype to allow us to derive an 'HFunctor' instance from any
-- instance of 'HBifunctor', using -XDerivingVia.
--
-- For example, because we have @instance 'HBifunctor' 'Day'@, we can
-- write:
--
-- @
-- deriving via ('WrappedHBifunctor' 'Day' f) instance 'HFunctor' ('Day' f)
-- @
--
-- to give us an automatic 'HFunctor' instance and save us some work.
newtype WrappedHBifunctor t (f :: k -> Type) (g :: k -> Type) (a :: k)
    = WrapHBifunctor { WrappedHBifunctor t f g a -> t f g a
unwrapHBifunctor :: t f g a }
  deriving a -> WrappedHBifunctor t f g b -> WrappedHBifunctor t f g a
(a -> b) -> WrappedHBifunctor t f g a -> WrappedHBifunctor t f g b
(forall a b.
 (a -> b) -> WrappedHBifunctor t f g a -> WrappedHBifunctor t f g b)
-> (forall a b.
    a -> WrappedHBifunctor t f g b -> WrappedHBifunctor t f g a)
-> Functor (WrappedHBifunctor t f g)
forall a b.
a -> WrappedHBifunctor t f g b -> WrappedHBifunctor t f g a
forall a b.
(a -> b) -> WrappedHBifunctor t f g a -> WrappedHBifunctor t f g b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (t :: (* -> *) -> (* -> *) -> * -> *) (f :: * -> *)
       (g :: * -> *) a b.
Functor (t f g) =>
a -> WrappedHBifunctor t f g b -> WrappedHBifunctor t f g a
forall (t :: (* -> *) -> (* -> *) -> * -> *) (f :: * -> *)
       (g :: * -> *) a b.
Functor (t f g) =>
(a -> b) -> WrappedHBifunctor t f g a -> WrappedHBifunctor t f g b
<$ :: a -> WrappedHBifunctor t f g b -> WrappedHBifunctor t f g a
$c<$ :: forall (t :: (* -> *) -> (* -> *) -> * -> *) (f :: * -> *)
       (g :: * -> *) a b.
Functor (t f g) =>
a -> WrappedHBifunctor t f g b -> WrappedHBifunctor t f g a
fmap :: (a -> b) -> WrappedHBifunctor t f g a -> WrappedHBifunctor t f g b
$cfmap :: forall (t :: (* -> *) -> (* -> *) -> * -> *) (f :: * -> *)
       (g :: * -> *) a b.
Functor (t f g) =>
(a -> b) -> WrappedHBifunctor t f g a -> WrappedHBifunctor t f g b
Functor

-- | Isomorphism between different varieities of ':+:'.
sumSum :: (f :+: g) <~> Sum f g
sumSum :: p (Sum f g a) (Sum f g a) -> p ((:+:) f g a) ((:+:) f g a)
sumSum = ((f :+: g) ~> Sum f g)
-> (Sum f g ~> (f :+: g)) -> (f :+: g) <~> Sum f g
forall k (f :: k -> *) (g :: k -> *).
(f ~> g) -> (g ~> f) -> f <~> g
isoF (f :+: g) ~> Sum f g
forall k (f :: k -> *) (g :: k -> *) (a :: k).
(:+:) f g a -> Sum f g a
to_ Sum f g ~> (f :+: g)
forall k (f :: k -> *) (g :: k -> *) (p :: k).
Sum f g p -> (:+:) f g p
from_
  where
    to_ :: (:+:) f g a -> Sum f g a
to_   (L1 x :: f a
x)  = f a -> Sum f g a
forall k (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
InL f a
x
    to_   (R1 y :: g a
y)  = g a -> Sum f g a
forall k (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
InR g a
y
    from_ :: Sum f g p -> (:+:) f g p
from_ (InL x :: f p
x) = f p -> (:+:) f g p
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 f p
x
    from_ (InR y :: g p
y) = g p -> (:+:) f g p
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 g p
y

-- | Isomorphism between different varieities of ':*:'.
prodProd :: (f :*: g) <~> Product f g
prodProd :: p (Product f g a) (Product f g a) -> p ((:*:) f g a) ((:*:) f g a)
prodProd = ((f :*: g) ~> Product f g)
-> (Product f g ~> (f :*: g)) -> (f :*: g) <~> Product f g
forall k (f :: k -> *) (g :: k -> *).
(f ~> g) -> (g ~> f) -> f <~> g
isoF (f :*: g) ~> Product f g
forall k (f :: k -> *) (g :: k -> *) (a :: k).
(:*:) f g a -> Product f g a
to_ Product f g ~> (f :*: g)
forall k (f :: k -> *) (g :: k -> *) (p :: k).
Product f g p -> (:*:) f g p
from_
  where
    to_ :: (:*:) f g a -> Product f g a
to_   (x :: f a
x :*: y :: g a
y)  = f a -> g a -> Product f g a
forall k (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
Pair f a
x g a
y
    from_ :: Product f g p -> (:*:) f g p
from_ (Pair x :: f p
x y :: g p
y) = f p
x f p -> g p -> (:*:) f g p
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g p
y

-- | Turn 'Identity' into any @'Applicative' f@.  Can be useful as an
-- argument to 'hmap', 'hbimap', or 'Data.HFunctor.Interpret.interpret'.
--
-- It is a more general form of 'Control.Monad.Morph.generalize' from
-- /mmorph/.
generalize :: Applicative f => Identity ~> f
generalize :: Identity ~> f
generalize (Identity x :: x
x) = x -> f x
forall (f :: * -> *) a. Applicative f => a -> f a
pure x
x

-- | Natural transformation from any functor @f@ into 'Proxy'.  Can be
-- useful for "zeroing out" a functor with 'hmap' or 'hbimap' or
-- 'Data.HFunctor.Interpret.interpret'.
absorb :: f ~> Proxy
absorb :: f x -> Proxy x
absorb _ = Proxy x
forall k (t :: k). Proxy t
Proxy

-- | Internal type, used to not require dlist-1.0
newtype NDL a = NDL ([a] -> NonEmpty a)

ndlSingleton :: a -> NDL a
ndlSingleton :: a -> NDL a
ndlSingleton x :: a
x = ([a] -> NonEmpty a) -> NDL a
forall a. ([a] -> NonEmpty a) -> NDL a
NDL (a
xa -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:|)

fromNDL :: NDL a -> NonEmpty a
fromNDL :: NDL a -> NonEmpty a
fromNDL (NDL f :: [a] -> NonEmpty a
f) = [a] -> NonEmpty a
f []

instance Semigroup (NDL a) where
    NDL x :: [a] -> NonEmpty a
x <> :: NDL a -> NDL a -> NDL a
<> NDL y :: [a] -> NonEmpty a
y = ([a] -> NonEmpty a) -> NDL a
forall a. ([a] -> NonEmpty a) -> NDL a
NDL ([a] -> NonEmpty a
x ([a] -> NonEmpty a) -> ([a] -> [a]) -> [a] -> NonEmpty a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (NonEmpty a -> [a]) -> ([a] -> NonEmpty a) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> NonEmpty a
y)

instance HFunctor Coyoneda where
    hmap :: (f ~> g) -> Coyoneda f ~> Coyoneda g
hmap = (f ~> g) -> Coyoneda f x -> Coyoneda g x
forall (f :: * -> *) (g :: * -> *) b.
(forall a. f a -> g a) -> Coyoneda f b -> Coyoneda g b
hoistCoyoneda

-- | @since 0.3.0.0
instance HFunctor CCY.Coyoneda where
    hmap :: (f ~> g) -> Coyoneda f ~> Coyoneda g
hmap f :: f ~> g
f (CCY.Coyoneda g :: x -> b
g x :: f b
x) = (x -> b) -> g b -> Coyoneda g x
forall a b (f :: * -> *). (a -> b) -> f b -> Coyoneda f a
CCY.Coyoneda x -> b
g (f b -> g b
f ~> g
f f b
x)

instance HFunctor Ap where
    hmap :: (f ~> g) -> Ap f ~> Ap g
hmap = (f ~> g) -> Ap f x -> Ap g x
forall (f :: * -> *) (g :: * -> *) b.
(forall a. f a -> g a) -> Ap f b -> Ap g b
hoistAp

instance HFunctor ListF where
    hmap :: (f ~> g) -> ListF f ~> ListF g
hmap f :: f ~> g
f (ListF xs :: [f x]
xs) = [g x] -> ListF g x
forall k (f :: k -> *) (a :: k). [f a] -> ListF f a
ListF ((f x -> g x) -> [f x] -> [g x]
forall a b. (a -> b) -> [a] -> [b]
map f x -> g x
f ~> g
f [f x]
xs)

instance HFunctor NonEmptyF where
    hmap :: (f ~> g) -> NonEmptyF f ~> NonEmptyF g
hmap f :: f ~> g
f (NonEmptyF xs :: NonEmpty (f x)
xs) = NonEmpty (g x) -> NonEmptyF g x
forall k (f :: k -> *) (a :: k). NonEmpty (f a) -> NonEmptyF f a
NonEmptyF ((f x -> g x) -> NonEmpty (f x) -> NonEmpty (g x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap f x -> g x
f ~> g
f NonEmpty (f x)
xs)

instance HFunctor MaybeF where
    hmap :: (f ~> g) -> MaybeF f ~> MaybeF g
hmap f :: f ~> g
f (MaybeF xs :: Maybe (f x)
xs) = Maybe (g x) -> MaybeF g x
forall k (f :: k -> *) (a :: k). Maybe (f a) -> MaybeF f a
MaybeF ((f x -> g x) -> Maybe (f x) -> Maybe (g x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap f x -> g x
f ~> g
f Maybe (f x)
xs)

instance HFunctor (MapF k) where
    hmap :: (f ~> g) -> MapF k f ~> MapF k g
hmap f :: f ~> g
f (MapF xs :: Map k (f x)
xs) = Map k (g x) -> MapF k g x
forall k k (f :: k -> *) (a :: k). Map k (f a) -> MapF k f a
MapF ((f x -> g x) -> Map k (f x) -> Map k (g x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap f x -> g x
f ~> g
f Map k (f x)
xs)

instance HFunctor (NEMapF k) where
    hmap :: (f ~> g) -> NEMapF k f ~> NEMapF k g
hmap f :: f ~> g
f (NEMapF xs :: NEMap k (f x)
xs) = NEMap k (g x) -> NEMapF k g x
forall k k (f :: k -> *) (a :: k). NEMap k (f a) -> NEMapF k f a
NEMapF ((f x -> g x) -> NEMap k (f x) -> NEMap k (g x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap f x -> g x
f ~> g
f NEMap k (f x)
xs)

instance HFunctor Alt.Alt where
    hmap :: (f ~> g) -> Alt f ~> Alt g
hmap = (f ~> g) -> Alt f x -> Alt g x
forall (f :: * -> *) (g :: * -> *) b.
(forall a. f a -> g a) -> Alt f b -> Alt g b
Alt.hoistAlt

instance HFunctor Step where
    hmap :: (f ~> g) -> Step f ~> Step g
hmap f :: f ~> g
f (Step n :: Natural
n x :: f x
x) = Natural -> g x -> Step g x
forall k (f :: k -> *) (a :: k). Natural -> f a -> Step f a
Step Natural
n (f x -> g x
f ~> g
f f x
x)

instance HFunctor Steps where
    hmap :: (f ~> g) -> Steps f ~> Steps g
hmap f :: f ~> g
f (Steps xs :: NEMap Natural (f x)
xs) = NEMap Natural (g x) -> Steps g x
forall k (f :: k -> *) (a :: k). NEMap Natural (f a) -> Steps f a
Steps (f x -> g x
f ~> g
f (f x -> g x) -> NEMap Natural (f x) -> NEMap Natural (g x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NEMap Natural (f x)
xs)

instance HFunctor Flagged where
    hmap :: (f ~> g) -> Flagged f ~> Flagged g
hmap f :: f ~> g
f (Flagged b :: Bool
b x :: f x
x) = Bool -> g x -> Flagged g x
forall k (f :: k -> *) (a :: k). Bool -> f a -> Flagged f a
Flagged Bool
b (f x -> g x
f ~> g
f f x
x)

instance HFunctor Free where
    hmap :: (f ~> g) -> Free f ~> Free g
hmap = (f ~> g) -> Free f x -> Free g x
forall (f :: * -> *) (g :: * -> *). (f ~> g) -> Free f ~> Free g
hoistFree

instance HFunctor Free1 where
    hmap :: (f ~> g) -> Free1 f ~> Free1 g
hmap = (f ~> g) -> Free1 f x -> Free1 g x
forall (f :: * -> *) (g :: * -> *). (f ~> g) -> Free1 f ~> Free1 g
hoistFree1

-- | Note that there is no 'Data.HFunctor.Interpret.Interpret' or
-- 'Data.HFunctor.Bind' instance, because 'Data.HFunctor.inject' requires
-- @'Functor' f@.
instance HFunctor MC.F where
    hmap :: (f ~> g) -> F f ~> F g
hmap = (f ~> g) -> F f x -> F g x
forall (f :: * -> *) (g :: * -> *) a.
(forall x. f x -> g x) -> F f a -> F g a
MC.hoistF

-- | Note that there is no 'Data.HFunctor.Interpret.Interpret' or
-- 'Data.HFunctor.Bind' instance, because 'Data.HFunctor.inject' requires
-- @'Functor' f@.
instance HFunctor MaybeT where
    hmap :: (f ~> g) -> MaybeT f ~> MaybeT g
hmap f :: f ~> g
f = (f (Maybe x) -> g (Maybe x)) -> MaybeT f x -> MaybeT g x
forall (m :: * -> *) a (n :: * -> *) b.
(m (Maybe a) -> n (Maybe b)) -> MaybeT m a -> MaybeT n b
mapMaybeT f (Maybe x) -> g (Maybe x)
f ~> g
f

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

instance HFunctor FA.Ap where
    hmap :: (f ~> g) -> Ap f ~> Ap g
hmap = (f ~> g) -> Ap f x -> Ap g x
forall (f :: * -> *) (g :: * -> *) b.
(forall a. f a -> g a) -> Ap f b -> Ap g b
FA.hoistAp

instance HFunctor FAF.Ap where
    hmap :: (f ~> g) -> Ap f ~> Ap g
hmap = (f ~> g) -> Ap f x -> Ap g x
forall (f :: * -> *) (g :: * -> *) a.
(forall x. f x -> g x) -> Ap f a -> Ap g a
FAF.hoistAp

instance HFunctor IdentityT where
    hmap :: (f ~> g) -> IdentityT f ~> IdentityT g
hmap = (f ~> g) -> IdentityT f x -> IdentityT g x
forall k1 k2 (m :: k1 -> *) (a :: k1) (n :: k2 -> *) (b :: k2).
(m a -> n b) -> IdentityT m a -> IdentityT n b
mapIdentityT

instance HFunctor Lift where
    hmap :: (f ~> g) -> Lift f ~> Lift g
hmap = (f ~> g) -> Lift f x -> Lift g x
forall (f :: * -> *) a (g :: * -> *).
(f a -> g a) -> Lift f a -> Lift g a
mapLift

instance HFunctor MaybeApply where
    hmap :: (f ~> g) -> MaybeApply f ~> MaybeApply g
hmap f :: f ~> g
f (MaybeApply x :: Either (f x) x
x) = Either (g x) x -> MaybeApply g x
forall (f :: * -> *) a. Either (f a) a -> MaybeApply f a
MaybeApply ((f x -> g x) -> Either (f x) x -> Either (g x) x
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first f x -> g x
f ~> g
f Either (f x) x
x)

instance HFunctor Backwards where
    hmap :: (f ~> g) -> Backwards f ~> Backwards g
hmap f :: f ~> g
f (Backwards x :: f x
x) = g x -> Backwards g x
forall k (f :: k -> *) (a :: k). f a -> Backwards f a
Backwards (f x -> g x
f ~> g
f f x
x)

instance HFunctor WrappedApplicative where
    hmap :: (f ~> g) -> WrappedApplicative f ~> WrappedApplicative g
hmap f :: f ~> g
f (WrapApplicative x :: f x
x) = g x -> WrappedApplicative g x
forall (f :: * -> *) a. f a -> WrappedApplicative f a
WrapApplicative (f x -> g x
f ~> g
f f x
x)

instance HFunctor (ReaderT r) where
    hmap :: (f ~> g) -> ReaderT r f ~> ReaderT r g
hmap = (f ~> g) -> ReaderT r f x -> ReaderT r g x
forall (m :: * -> *) a (n :: * -> *) b r.
(m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT

instance HFunctor Tagged where
    hmap :: (f ~> g) -> Tagged f ~> Tagged g
hmap _ = Tagged f x -> Tagged g x
forall a b. Coercible a b => a -> b
coerce

instance HFunctor Reverse where
    hmap :: (f ~> g) -> Reverse f ~> Reverse g
hmap f :: f ~> g
f (Reverse x :: f x
x) = g x -> Reverse g x
forall k (f :: k -> *) (a :: k). f a -> Reverse f a
Reverse (f x -> g x
f ~> g
f f x
x)

instance (HFunctor s, HFunctor t) => HFunctor (ComposeT s t) where
    hmap :: (f ~> g) -> ComposeT s t f ~> ComposeT s t g
hmap f :: f ~> g
f (ComposeT x :: s (t f) x
x) = s (t g) x -> ComposeT s t g x
forall (f :: (* -> *) -> * -> *) (g :: (* -> *) -> * -> *)
       (m :: * -> *) a.
f (g m) a -> ComposeT f g m a
ComposeT (s (t g) x -> ComposeT s t g x) -> s (t g) x -> ComposeT s t g x
forall a b. (a -> b) -> a -> b
$ (t f ~> t g) -> s (t f) x -> s (t g) x
forall k k (t :: (k -> *) -> k -> *) (f :: k -> *) (g :: k -> *).
HFunctor t =>
(f ~> g) -> t f ~> t g
hmap ((f ~> g) -> t f ~> t g
forall k k (t :: (k -> *) -> k -> *) (f :: k -> *) (g :: k -> *).
HFunctor t =>
(f ~> g) -> t f ~> t g
hmap f ~> g
f) s (t f) x
x

instance Functor f => HFunctor ((:.:) f) where
    hmap :: (f ~> g) -> (f :.: f) ~> (f :.: g)
hmap f :: f ~> g
f (Comp1 x :: f (f x)
x) = f (g x) -> (:.:) f g x
forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1).
f (g p) -> (:.:) f g p
Comp1 (f x -> g x
f ~> g
f (f x -> g x) -> f (f x) -> f (g x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f (f x)
x)

instance HFunctor (M1 i c) where
    hmap :: (f ~> g) -> M1 i c f ~> M1 i c g
hmap f :: f ~> g
f (M1 x :: f x
x) = g x -> M1 i c g x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (f x -> g x
f ~> g
f f x
x)

instance HFunctor Void2 where
    hmap :: (f ~> g) -> Void2 f ~> Void2 g
hmap _ = Void2 f x -> Void2 g x
forall a b. Coercible a b => a -> b
coerce

instance HFunctor (EnvT e) where
    hmap :: (f ~> g) -> EnvT e f ~> EnvT e g
hmap f :: f ~> g
f (EnvT e :: e
e x :: f x
x) = e -> g x -> EnvT e g x
forall e (w :: * -> *) a. e -> w a -> EnvT e w a
EnvT e
e (f x -> g x
f ~> g
f f x
x)

instance HFunctor Rec where
    hmap :: (f ~> g) -> Rec f ~> Rec g
hmap = (f ~> g) -> Rec f x -> Rec g x
forall u (f :: u -> *) (g :: u -> *) (rs :: [u]).
(forall (x :: u). f x -> g x) -> Rec f rs -> Rec g rs
rmap

instance HFunctor CoRec where
    hmap :: (f ~> g) -> CoRec f ~> CoRec g
hmap f :: f ~> g
f (CoRec x :: f a1
x) = g a1 -> CoRec g x
forall k (a1 :: k) (b :: [k]) (a :: k -> *).
RElem a1 b (RIndex a1 b) =>
a a1 -> CoRec a b
CoRec (f a1 -> g a1
f ~> g
f f a1
x)

-- | @since 0.3.0.0
instance HFunctor SOP.NP where
    hmap :: (f ~> g) -> NP f ~> NP g
hmap f :: f ~> g
f = NP g '[]
-> (forall (y :: k) (ys :: [k]). f y -> NP g ys -> NP g (y : ys))
-> NP f x
-> NP g x
forall k (r :: [k] -> *) (f :: k -> *) (xs :: [k]).
r '[]
-> (forall (y :: k) (ys :: [k]). f y -> r ys -> r (y : ys))
-> NP f xs
-> r xs
SOP.cata_NP NP g '[]
forall k (a :: k -> *). NP a '[]
SOP.Nil (g y -> NP g ys -> NP g (y : ys)
forall k (a :: k -> *) (x :: k) (xs :: [k]).
a x -> NP a xs -> NP a (x : xs)
(SOP.:*) (g y -> NP g ys -> NP g (y : ys))
-> (f y -> g y) -> f y -> NP g ys -> NP g (y : ys)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f y -> g y
f ~> g
f)

-- | @since 0.3.0.0
instance HFunctor SOP.NS where
    hmap :: (f ~> g) -> NS f ~> NS g
hmap f :: f ~> g
f = (forall (y :: k) (ys :: [k]). f y -> NS g (y : ys))
-> (forall (y :: k) (ys :: [k]). NS g ys -> NS g (y : ys))
-> NS f x
-> NS g x
forall k (r :: [k] -> *) (f :: k -> *) (xs :: [k]).
(forall (y :: k) (ys :: [k]). f y -> r (y : ys))
-> (forall (y :: k) (ys :: [k]). r ys -> r (y : ys))
-> NS f xs
-> r xs
SOP.cata_NS (g y -> NS g (y : ys)
forall k (a :: k -> *) (x :: k) (xs :: [k]). a x -> NS a (x : xs)
SOP.Z (g y -> NS g (y : ys)) -> (f y -> g y) -> f y -> NS g (y : ys)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f y -> g y
f ~> g
f) forall (y :: k) (ys :: [k]). NS g ys -> NS g (y : ys)
forall k (a :: k -> *) (xs :: [k]) (x :: k).
NS a xs -> NS a (x : xs)
SOP.S

instance HBifunctor (:*:) where
    hleft :: (f ~> j) -> (f :*: g) ~> (j :*: g)
hleft  f :: f ~> j
f (x :: f x
x :*: y :: g x
y) = f x -> j x
f ~> j
f f x
x j x -> g x -> (:*:) j g x
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*:   g x
y
    hright :: (g ~> l) -> (f :*: g) ~> (f :*: l)
hright g :: g ~> l
g (x :: f x
x :*: y :: g x
y) =   f x
x f x -> l x -> (:*:) f l x
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g x -> l x
g ~> l
g g x
y
    hbimap :: (f ~> j) -> (g ~> l) -> (f :*: g) ~> (j :*: l)
hbimap f :: f ~> j
f g :: g ~> l
g (x :: f x
x :*: y :: g x
y) = f x -> j x
f ~> j
f f x
x j x -> l x -> (:*:) j l x
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g x -> l x
g ~> l
g g x
y

instance HBifunctor Product where
    hleft :: (f ~> j) -> Product f g ~> Product j g
hleft  f :: f ~> j
f (Pair x :: f x
x y :: g x
y)   = j x -> g x -> Product j g x
forall k (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
Pair (f x -> j x
f ~> j
f f x
x)    g x
y
    hright :: (g ~> l) -> Product f g ~> Product f l
hright g :: g ~> l
g (Pair x :: f x
x y :: g x
y)   = f x -> l x -> Product f l x
forall k (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
Pair    f x
x  (g x -> l x
g ~> l
g g x
y)
    hbimap :: (f ~> j) -> (g ~> l) -> Product f g ~> Product j l
hbimap f :: f ~> j
f g :: g ~> l
g (Pair x :: f x
x y :: g x
y) = j x -> l x -> Product j l x
forall k (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
Pair (f x -> j x
f ~> j
f f x
x) (g x -> l x
g ~> l
g g x
y)

instance HBifunctor Day where
    hleft :: (f ~> j) -> Day f g ~> Day j g
hleft  = (f ~> j) -> Day f g x -> Day j g x
forall (f :: * -> *) (g :: * -> *) (h :: * -> *) a.
(forall x. f x -> g x) -> Day f h a -> Day g h a
D.trans1
    hright :: (g ~> l) -> Day f g ~> Day f l
hright = (g ~> l) -> Day f g x -> Day f l x
forall (g :: * -> *) (h :: * -> *) (f :: * -> *) a.
(forall x. g x -> h x) -> Day f g a -> Day f h a
D.trans2
    hbimap :: (f ~> j) -> (g ~> l) -> Day f g ~> Day j l
hbimap f :: f ~> j
f g :: g ~> l
g (Day x :: f b
x y :: g c
y z :: b -> c -> x
z) = j b -> l c -> (b -> c -> x) -> Day j l x
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (b -> c -> a) -> Day f g a
Day (f b -> j b
f ~> j
f f b
x) (g c -> l c
g ~> l
g g c
y) b -> c -> x
z

-- | @since 0.3.0.0
instance HBifunctor CD.Day where
    hleft :: (f ~> j) -> Day f g ~> Day j g
hleft  = (f ~> j) -> Day f g x -> Day j g x
forall (f :: * -> *) (g :: * -> *) (h :: * -> *) a.
(forall x. f x -> g x) -> Day f h a -> Day g h a
CD.trans1
    hright :: (g ~> l) -> Day f g ~> Day f l
hright = (g ~> l) -> Day f g x -> Day f l x
forall (g :: * -> *) (h :: * -> *) (f :: * -> *) a.
(forall x. g x -> h x) -> Day f g a -> Day f h a
CD.trans2
    hbimap :: (f ~> j) -> (g ~> l) -> Day f g ~> Day j l
hbimap f :: f ~> j
f g :: g ~> l
g (CD.Day x :: f b
x y :: g c
y z :: x -> (b, c)
z) = j b -> l c -> (x -> (b, c)) -> Day j l x
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
CD.Day (f b -> j b
f ~> j
f f b
x) (g c -> l c
g ~> l
g g c
y) x -> (b, c)
z

-- | @since 0.3.0.0
instance HBifunctor Night where
    hleft :: (f ~> j) -> Night f g ~> Night j g
hleft  = (f ~> j) -> Night f g x -> Night j g x
forall (f :: * -> *) (j :: * -> *) (g :: * -> *).
(f ~> j) -> Night f g ~> Night j g
N.trans1
    hright :: (g ~> l) -> Night f g ~> Night f l
hright = (g ~> l) -> Night f g x -> Night f l x
forall (g :: * -> *) (l :: * -> *) (f :: * -> *).
(g ~> l) -> Night f g ~> Night f l
N.trans2
    hbimap :: (f ~> j) -> (g ~> l) -> Night f g ~> Night j l
hbimap f :: f ~> j
f g :: g ~> l
g (Night x :: f b
x y :: g c
y z :: x -> Either b c
z) = j b -> l c -> (x -> Either b c) -> Night j l x
forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
Night (f b -> j b
f ~> j
f f b
x) (g c -> l c
g ~> l
g g c
y) x -> Either b c
z

instance HBifunctor (:+:) where
    hleft :: (f ~> j) -> (f :+: g) ~> (j :+: g)
hleft f :: f ~> j
f = \case
      L1 x :: f x
x -> j x -> (:+:) j g x
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 (f x -> j x
f ~> j
f f x
x)
      R1 y :: g x
y -> g x -> (:+:) j g x
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 g x
y

    hright :: (g ~> l) -> (f :+: g) ~> (f :+: l)
hright g :: g ~> l
g = \case
      L1 x :: f x
x -> f x -> (:+:) f l x
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 f x
x
      R1 y :: g x
y -> l x -> (:+:) f l x
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 (g x -> l x
g ~> l
g g x
y)

    hbimap :: (f ~> j) -> (g ~> l) -> (f :+: g) ~> (j :+: l)
hbimap f :: f ~> j
f g :: g ~> l
g = \case
      L1 x :: f x
x -> j x -> (:+:) j l x
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 (f x -> j x
f ~> j
f f x
x)
      R1 y :: g x
y -> l x -> (:+:) j l x
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 (g x -> l x
g ~> l
g g x
y)

instance HBifunctor Sum where
    hleft :: (f ~> j) -> Sum f g ~> Sum j g
hleft f :: f ~> j
f = \case
      InL x :: f x
x -> j x -> Sum j g x
forall k (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
InL (f x -> j x
f ~> j
f f x
x)
      InR y :: g x
y -> g x -> Sum j g x
forall k (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
InR g x
y

    hright :: (g ~> l) -> Sum f g ~> Sum f l
hright g :: g ~> l
g = \case
      InL x :: f x
x -> f x -> Sum f l x
forall k (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
InL f x
x
      InR y :: g x
y -> l x -> Sum f l x
forall k (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
InR (g x -> l x
g ~> l
g g x
y)

    hbimap :: (f ~> j) -> (g ~> l) -> Sum f g ~> Sum j l
hbimap f :: f ~> j
f g :: g ~> l
g = \case
      InL x :: f x
x -> j x -> Sum j l x
forall k (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
InL (f x -> j x
f ~> j
f f x
x)
      InR y :: g x
y -> l x -> Sum j l x
forall k (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
InR (g x -> l x
g ~> l
g g x
y)

instance HBifunctor These1 where
    hbimap :: (f ~> j) -> (g ~> l) -> These1 f g ~> These1 j l
hbimap f :: f ~> j
f g :: g ~> l
g = \case
      This1  x :: f x
x   -> j x -> These1 j l x
forall (f :: * -> *) (g :: * -> *) a. f a -> These1 f g a
This1  (f x -> j x
f ~> j
f f x
x)
      That1    y :: g x
y -> l x -> These1 j l x
forall (f :: * -> *) (g :: * -> *) a. g a -> These1 f g a
That1        (g x -> l x
g ~> l
g g x
y)
      These1 x :: f x
x y :: g x
y -> j x -> l x -> These1 j l x
forall (f :: * -> *) (g :: * -> *) a. f a -> g a -> These1 f g a
These1 (f x -> j x
f ~> j
f f x
x) (g x -> l x
g ~> l
g g x
y)

instance HBifunctor Joker where
    hleft :: (f ~> j) -> Joker f g ~> Joker j g
hleft  f :: f ~> j
f   (Joker x :: f x
x) = j x -> Joker j g x
forall k k1 (g :: k -> *) (a :: k1) (b :: k). g b -> Joker g a b
Joker (f x -> j x
f ~> j
f f x
x)
    hright :: (g ~> l) -> Joker f g ~> Joker f l
hright   _           = Joker f g x -> Joker f l x
forall a b. Coercible a b => a -> b
coerce
    hbimap :: (f ~> j) -> (g ~> l) -> Joker f g ~> Joker j l
hbimap f :: f ~> j
f _ (Joker x :: f x
x) = j x -> Joker j l x
forall k k1 (g :: k -> *) (a :: k1) (b :: k). g b -> Joker g a b
Joker (f x -> j x
f ~> j
f f x
x)

instance HBifunctor Void3 where
    hleft :: (f ~> j) -> Void3 f g ~> Void3 j g
hleft  _   = Void3 f g x -> Void3 j g x
forall a b. Coercible a b => a -> b
coerce
    hright :: (g ~> l) -> Void3 f g ~> Void3 f l
hright   _ = Void3 f g x -> Void3 f l x
forall a b. Coercible a b => a -> b
coerce
    hbimap :: (f ~> j) -> (g ~> l) -> Void3 f g ~> Void3 j l
hbimap _ _ = Void3 f g x -> Void3 j l x
forall a b. Coercible a b => a -> b
coerce

instance HBifunctor Comp where
    hleft :: (f ~> j) -> Comp f g ~> Comp j g
hleft  f :: f ~> j
f   (x :: f x
x :>>= h :: x -> g x
h) = f x -> j x
f ~> j
f f x
x j x -> (x -> g x) -> Comp j g x
forall k (f :: * -> *) (g :: k -> *) (a :: k) x.
f x -> (x -> g a) -> Comp f g a
:>>= x -> g x
h
    hright :: (g ~> l) -> Comp f g ~> Comp f l
hright   g :: g ~> l
g (x :: f x
x :>>= h :: x -> g x
h) =   f x
x f x -> (x -> l x) -> Comp f l x
forall k (f :: * -> *) (g :: k -> *) (a :: k) x.
f x -> (x -> g a) -> Comp f g a
:>>= (g x -> l x
g ~> l
g (g x -> l x) -> (x -> g x) -> x -> l x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> g x
h)
    hbimap :: (f ~> j) -> (g ~> l) -> Comp f g ~> Comp j l
hbimap f :: f ~> j
f g :: g ~> l
g (x :: f x
x :>>= h :: x -> g x
h) = f x -> j x
f ~> j
f f x
x j x -> (x -> l x) -> Comp j l x
forall k (f :: * -> *) (g :: k -> *) (a :: k) x.
f x -> (x -> g a) -> Comp f g a
:>>= (g x -> l x
g ~> l
g (g x -> l x) -> (x -> g x) -> x -> l x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> g x
h)

instance HBifunctor t => HFunctor (WrappedHBifunctor t f) where
    hmap :: (f ~> g) -> WrappedHBifunctor t f f ~> WrappedHBifunctor t f g
hmap f :: f ~> g
f = t f g x -> WrappedHBifunctor t f g x
forall k (t :: (k -> *) -> (k -> *) -> k -> *) (f :: k -> *)
       (g :: k -> *) (a :: k).
t f g a -> WrappedHBifunctor t f g a
WrapHBifunctor (t f g x -> WrappedHBifunctor t f g x)
-> (WrappedHBifunctor t f f x -> t f g x)
-> WrappedHBifunctor t f f x
-> WrappedHBifunctor t f g x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f ~> g) -> t f f ~> t f g
forall k (t :: (k -> *) -> (k -> *) -> k -> *) (g :: k -> *)
       (l :: k -> *) (f :: k -> *).
HBifunctor t =>
(g ~> l) -> t f g ~> t f l
hright f ~> g
f (t f f x -> t f g x)
-> (WrappedHBifunctor t f f x -> t f f x)
-> WrappedHBifunctor t f f x
-> t f g x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WrappedHBifunctor t f f x -> t f f x
forall k (t :: (k -> *) -> (k -> *) -> k -> *) (f :: k -> *)
       (g :: k -> *) (a :: k).
WrappedHBifunctor t f g a -> t f g a
unwrapHBifunctor

deriving via (WrappedHBifunctor Day f)     instance HFunctor (Day f)
deriving via (WrappedHBifunctor (:*:) f)   instance HFunctor ((:*:) f)
deriving via (WrappedHBifunctor (:+:) f)   instance HFunctor ((:+:) f)
deriving via (WrappedHBifunctor Product f) instance HFunctor (Product f)
deriving via (WrappedHBifunctor Sum f)     instance HFunctor (Sum f)
deriving via (WrappedHBifunctor Joker f)   instance HFunctor (Joker f)
deriving via (WrappedHBifunctor These1 f)  instance HFunctor (These1 f)
deriving via (WrappedHBifunctor Void3 f)   instance HFunctor (Void3 f)
deriving via (WrappedHBifunctor Comp f)    instance HFunctor (Comp f)