{-# OPTIONS_GHC -Wno-orphans #-}

-- | Single Parameter Functors of arbitrary categories.
module Kindly.Functor
  ( Functor,
    fmap,
    contramap,
    invmap,
    Filterable,
    mapMaybe,
    catMaybes,
    filter,
  )
where

--------------------------------------------------------------------------------

import Control.Applicative (Const, WrappedArrow, WrappedMonad, ZipList)
import Control.Arrow (Arrow, ArrowMonad, Kleisli (..))
import Control.Category (Category (..))
import Control.Exception (Handler)
import Control.Monad (Monad)
import Control.Monad.ST (ST)
import Control.Monad.ST.Lazy qualified as Lazy
import Data.Complex (Complex)
import Data.Either (Either)
import Data.Functor qualified as Hask
import Data.Functor.Compose (Compose (..))
import Data.Functor.Contravariant (Op (..), Predicate)
import Data.Functor.Contravariant qualified as Hask
import Data.Functor.Identity (Identity (..))
import Data.Functor.Product (Product (..))
import Data.Functor.Sum (Sum (..))
import Data.Kind (Constraint, Type)
import Data.List.NonEmpty (NonEmpty)
import Data.Maybe (Maybe (..))
import Data.Monoid qualified as Monoid
import Data.Ord (Down)
import Data.Profunctor qualified as Hask.Profunctor
import Data.Proxy (Proxy)
import Data.Semigroup qualified as Semigroup
import Data.These (These)
import Data.Tuple (Solo)
import Foreign (Ptr)
import GHC.Arr (Array)
import GHC.Base (Char, Double, IO, Int, Word, ($))
import GHC.Conc (STM)
import GHC.Exts (Float)
import GHC.Generics (K1, M1 (..), Par1, Rec1 (..), U1, URec, V1, (:*:) (..), (:+:) (..), (:.:) (..))
import Kindly.Class
import Kindly.Iso
import System.Console.GetOpt (ArgDescr, ArgOrder, OptDescr)
import Text.ParserCombinators.ReadP (ReadP)
import Text.ParserCombinators.ReadPrec (ReadPrec)
import Witherable qualified as Hask
import Prelude (Bool)

--------------------------------------------------------------------------------

-- | A 'CategoricalFunctor' of kind @Type -> Type@ mapping from an
-- arbitrary category @cat@ to @->@.
type Functor :: (Type -> Type -> Type) -> (Type -> Type) -> Constraint
type Functor cat p = (MapArg1 cat p)

-- | Lift a function @cat a b@ into a function @f a -> f b@.
fmap :: forall cat f. (Functor cat f) => forall a b. (a `cat` b) -> f a -> f b
fmap :: forall (cat :: * -> * -> *) (f :: * -> *) a b.
Functor cat f =>
cat a b -> f a -> f b
fmap = cat a b -> f a -> f b
forall a b. cat a b -> f a -> f b
forall {from} (cat1 :: Cat from) (p :: from -> *) (a :: from)
       (b :: from).
MapArg1 cat1 p =>
cat1 a b -> p a -> p b
map1

-- | A specialization of 'fmap' for contravariant functors as defined
-- in 'Data.Functor.Contravariant.'
--
-- TODO: Do we keep this around? This is nice to have so that library
-- users don't have to manually pack functions in 'Op'.
contramap :: (Functor Op p) => (a -> b) -> p b -> p a
contramap :: forall (p :: * -> *) a b. Functor Op p => (a -> b) -> p b -> p a
contramap = Op b a -> p b -> p a
forall a b. Op a b -> p a -> p b
forall (cat :: * -> * -> *) (f :: * -> *) a b.
Functor cat f =>
cat a b -> f a -> f b
fmap (Op b a -> p b -> p a)
-> ((a -> b) -> Op b a) -> (a -> b) -> p b -> p a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a -> b) -> Op b a
forall a b. (b -> a) -> Op a b
Op

-- | A specialization of 'fmap' for invariant functors as defined
-- in 'Data.Functor.Invariant.'
--
-- TODO: Do we keep this around? This is nice to have so that library
-- users don't have to manually pack functions in 'Iso'.
invmap :: (Functor (<->) f) => (a -> b) -> (b -> a) -> f a -> f b
invmap :: forall (f :: * -> *) a b.
Functor (<->) f =>
(a -> b) -> (b -> a) -> f a -> f b
invmap a -> b
f b -> a
g = Iso (->) a b -> f a -> f b
forall a b. Iso (->) a b -> f a -> f b
forall (cat :: * -> * -> *) (f :: * -> *) a b.
Functor cat f =>
cat a b -> f a -> f b
fmap ((a -> b) -> (b -> a) -> Iso (->) a b
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k).
cat a b -> cat b a -> Iso cat a b
Iso a -> b
f b -> a
g)

-- TODO: 'Filterable' is currently unusable due to fundeps. This can
-- be fixed by making it @FunctorOf (Hask.Star Maybe) (->) p@, but I
-- think we can do better by switching away from associated types.
type Filterable p = Functor (Hask.Profunctor.Star Maybe) p

-- | A specialization of 'fmap' for filterable functors as defined
-- in 'Witherable'
--
-- TODO: Do we keep this around? This is nice to have so that library
-- users don't have to manually pack functions in 'Hask.Star'.
mapMaybe :: (Filterable f) => (a -> Maybe b) -> f a -> f b
mapMaybe :: forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe a -> Maybe b
f = Dom f a b -> Cod f (f a) (f b)
forall a b. Dom f a b -> Cod f (f a) (f b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map ((a -> Maybe b) -> Star Maybe a b
forall {k} (f :: k -> *) d (c :: k). (d -> f c) -> Star f d c
Hask.Profunctor.Star a -> Maybe b
f)

-- | The 'catMaybes' function takes a list of 'Maybe's and returns
-- a list of all the 'Just' values.
--
-- TODO: Do we keep this around? This is nice to have so that library
-- users don't have to manually pack functions in 'Hask.Star'.
catMaybes :: (Filterable f) => f (Maybe a) -> f a
catMaybes :: forall (f :: * -> *) a. Filterable f => f (Maybe a) -> f a
catMaybes = Dom f (Maybe a) a -> Cod f (f (Maybe a)) (f a)
forall a b. Dom f a b -> Cod f (f a) (f b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map ((Maybe a -> Maybe a) -> Star Maybe (Maybe a) a
forall {k} (f :: k -> *) d (c :: k). (d -> f c) -> Star f d c
Hask.Profunctor.Star Maybe a -> Maybe a
forall a. a -> a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id)

-- | Applied to a predicate and a functor @f a@, returns the those
-- elements that satisfy the predicate.
--
-- TODO: Do we keep this around? This is nice to have so that library
-- users don't have to manually pack functions in 'Hask.Star'.
filter :: (Filterable f) => (a -> Bool) -> f a -> f a
filter :: forall (f :: * -> *) a. Filterable f => (a -> Bool) -> f a -> f a
filter a -> Bool
f = Dom f a a -> Cod f (f a) (f a)
forall a b. Dom f a b -> Cod f (f a) (f b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map ((a -> Maybe a) -> Star Maybe a a
forall {k} (f :: k -> *) d (c :: k). (d -> f c) -> Star f d c
Hask.Profunctor.Star (\a
a -> if a -> Bool
f a
a then a -> Maybe a
forall a. a -> Maybe a
Just a
a else Maybe a
forall a. Maybe a
Nothing))

--------------------------------------------------------------------------------

newtype FromFunctor f a = FromFunctor (f a)
  deriving newtype ((forall a b. (a -> b) -> FromFunctor f a -> FromFunctor f b)
-> (forall a b. a -> FromFunctor f b -> FromFunctor f a)
-> Functor (FromFunctor f)
forall a b. a -> FromFunctor f b -> FromFunctor f a
forall a b. (a -> b) -> FromFunctor f a -> FromFunctor f b
forall (f :: * -> *) a b.
Functor f =>
a -> FromFunctor f b -> FromFunctor f a
forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> FromFunctor f a -> FromFunctor f b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> FromFunctor f a -> FromFunctor f b
fmap :: forall a b. (a -> b) -> FromFunctor f a -> FromFunctor f b
$c<$ :: forall (f :: * -> *) a b.
Functor f =>
a -> FromFunctor f b -> FromFunctor f a
<$ :: forall a b. a -> FromFunctor f b -> FromFunctor f a
Hask.Functor)

instance (Hask.Functor f) => CategoricalFunctor (FromFunctor f) where
  type Dom (FromFunctor f) = (->)
  type Cod (FromFunctor f) = (->)

  map :: (a -> b) -> FromFunctor f a -> FromFunctor f b
  map :: forall a b. (a -> b) -> FromFunctor f a -> FromFunctor f b
map = (a -> b) -> FromFunctor f a -> FromFunctor f b
forall a b. (a -> b) -> FromFunctor f a -> FromFunctor f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
Hask.fmap

--------------------------------------------------------------------------------
-- Covariant Functor instances

deriving via (FromFunctor ZipList) instance CategoricalFunctor ZipList

deriving via (FromFunctor Handler) instance CategoricalFunctor Handler

deriving via (FromFunctor Complex) instance CategoricalFunctor Complex

deriving via (FromFunctor Identity) instance CategoricalFunctor Identity

deriving via (FromFunctor Monoid.First) instance CategoricalFunctor Monoid.First

deriving via (FromFunctor Monoid.Last) instance CategoricalFunctor Monoid.Last

deriving via (FromFunctor Down) instance CategoricalFunctor Down

deriving via (FromFunctor Semigroup.First) instance CategoricalFunctor Semigroup.First

deriving via (FromFunctor Semigroup.Last) instance CategoricalFunctor Semigroup.Last

deriving via (FromFunctor Semigroup.Max) instance CategoricalFunctor Semigroup.Max

deriving via (FromFunctor Semigroup.Min) instance CategoricalFunctor Semigroup.Min

deriving via (FromFunctor Semigroup.Dual) instance CategoricalFunctor Semigroup.Dual

deriving via (FromFunctor Semigroup.Product) instance CategoricalFunctor Semigroup.Product

deriving via (FromFunctor Semigroup.Sum) instance CategoricalFunctor Semigroup.Sum

deriving via (FromFunctor NonEmpty) instance CategoricalFunctor NonEmpty

deriving via (FromFunctor STM) instance CategoricalFunctor STM

deriving via (FromFunctor Par1) instance CategoricalFunctor Par1

deriving via (FromFunctor ArgDescr) instance CategoricalFunctor ArgDescr

deriving via (FromFunctor ArgOrder) instance CategoricalFunctor ArgOrder

deriving via (FromFunctor OptDescr) instance CategoricalFunctor OptDescr

deriving via (FromFunctor ReadP) instance CategoricalFunctor ReadP

deriving via (FromFunctor ReadPrec) instance CategoricalFunctor ReadPrec

deriving via (FromFunctor IO) instance CategoricalFunctor IO

deriving via (FromFunctor Maybe) instance CategoricalFunctor Maybe

deriving via (FromFunctor Solo) instance CategoricalFunctor Solo

deriving via (FromFunctor []) instance CategoricalFunctor []

deriving via (FromFunctor (WrappedMonad m)) instance (Monad m) => CategoricalFunctor (WrappedMonad m)

deriving via (FromFunctor (ArrowMonad a)) instance (Arrow a) => CategoricalFunctor (ArrowMonad a)

deriving via (FromFunctor (Lazy.ST s)) instance CategoricalFunctor (Lazy.ST s)

deriving via (FromFunctor (Either a)) instance CategoricalFunctor (Either a)

deriving via (FromFunctor (These a)) instance CategoricalFunctor (These a)

deriving via (FromFunctor Proxy) instance CategoricalFunctor (Proxy :: Type -> Type)

deriving via (FromFunctor (Semigroup.Arg a)) instance CategoricalFunctor (Semigroup.Arg a)

deriving via (FromFunctor (Array i)) instance CategoricalFunctor (Array i)

deriving via (FromFunctor U1) instance CategoricalFunctor (U1 :: Type -> Type)

deriving via (FromFunctor V1) instance CategoricalFunctor (V1 :: Type -> Type)

deriving via (FromFunctor (ST s)) instance CategoricalFunctor (ST s)

deriving via (FromFunctor ((,) a)) instance CategoricalFunctor ((,) a)

deriving via (FromFunctor (WrappedArrow a b)) instance (Arrow a) => CategoricalFunctor (WrappedArrow a b)

-- TODO: Figure out if these instances be written with Deriving Via.
instance (FunctorOf (->) (->) m) => CategoricalFunctor (Kleisli m a) where
  type Dom (Kleisli m a) = (->)
  type Cod (Kleisli m a) = (->)

  map :: (a1 -> b) -> Kleisli m a a1 -> Kleisli m a b
  map :: forall a1 b. (a1 -> b) -> Kleisli m a a1 -> Kleisli m a b
map a1 -> b
f (Kleisli a -> m a1
m) = (a -> m b) -> Kleisli m a b
forall (m :: * -> *) a b. (a -> m b) -> Kleisli m a b
Kleisli ((a -> m b) -> Kleisli m a b) -> (a -> m b) -> Kleisli m a b
forall a b. (a -> b) -> a -> b
$ \a
a -> Dom m a1 b -> Cod m (m a1) (m b)
forall a b. Dom m a b -> Cod m (m a) (m b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom m a1 b
a1 -> b
f (a -> m a1
m a
a)

deriving via (FromFunctor (Const m)) instance CategoricalFunctor (Const m :: Type -> Type)

instance (FunctorOf (->) (->) f) => CategoricalFunctor (Monoid.Ap f) where
  type Dom (Monoid.Ap f) = (->)
  type Cod (Monoid.Ap f) = (->)

  map :: forall a b. Dom (Ap f) a b -> Cod (Ap f) (Ap f a) (Ap f b)
map Dom (Ap f) a b
f (Monoid.Ap f a
m) = f b -> Ap f b
forall {k} (f :: k -> *) (a :: k). f a -> Ap f a
Monoid.Ap (f b -> Ap f b) -> f b -> Ap f b
forall a b. (a -> b) -> a -> b
$ Dom f a b -> Cod f (f a) (f b)
forall a b. Dom f a b -> Cod f (f a) (f b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom f a b
Dom (Ap f) a b
f f a
m

instance (FunctorOf (->) (->) f) => CategoricalFunctor (Monoid.Alt f) where
  type Dom (Monoid.Alt f) = (->)
  type Cod (Monoid.Alt f) = (->)

  map :: forall a b. Dom (Alt f) a b -> Cod (Alt f) (Alt f a) (Alt f b)
map Dom (Alt f) a b
f (Monoid.Alt f a
m) = f b -> Alt f b
forall {k} (f :: k -> *) (a :: k). f a -> Alt f a
Monoid.Alt (f b -> Alt f b) -> f b -> Alt f b
forall a b. (a -> b) -> a -> b
$ Dom f a b -> Cod f (f a) (f b)
forall a b. Dom f a b -> Cod f (f a) (f b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom f a b
Dom (Alt f) a b
f f a
m

instance (FunctorOf (->) (->) f) => CategoricalFunctor (Rec1 f) where
  type Dom (Rec1 f) = (->)
  type Cod (Rec1 f) = (->)

  map :: forall a b. Dom (Rec1 f) a b -> Cod (Rec1 f) (Rec1 f a) (Rec1 f b)
map Dom (Rec1 f) a b
f (Rec1 f a
m) = f b -> Rec1 f b
forall k (f :: k -> *) (p :: k). f p -> Rec1 f p
Rec1 (f b -> Rec1 f b) -> f b -> Rec1 f b
forall a b. (a -> b) -> a -> b
$ Dom f a b -> Cod f (f a) (f b)
forall a b. Dom f a b -> Cod f (f a) (f b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom f a b
Dom (Rec1 f) a b
f f a
m

deriving via (FromFunctor (URec (Ptr ()))) instance CategoricalFunctor (URec (Ptr ()) :: Type -> Type)

deriving via (FromFunctor (URec Char)) instance CategoricalFunctor (URec Char :: Type -> Type)

deriving via (FromFunctor (URec Double)) instance CategoricalFunctor (URec Double :: Type -> Type)

deriving via (FromFunctor (URec Float)) instance CategoricalFunctor (URec Float :: Type -> Type)

deriving via (FromFunctor (URec Int)) instance CategoricalFunctor (URec Int :: Type -> Type)

deriving via (FromFunctor (URec Word)) instance CategoricalFunctor (URec Word :: Type -> Type)

deriving via (FromFunctor ((,,) a b)) instance CategoricalFunctor ((,,) a b)

instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => CategoricalFunctor (Product f g) where
  type Dom (Product f g) = (->)
  type Cod (Product f g) = (->)

  map :: forall a b.
Dom (Product f g) a b
-> Cod (Product f g) (Product f g a) (Product f g b)
map Dom (Product f g) a b
f (Pair f a
m1 g a
m2) = f b -> g b -> Product f g b
forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
Pair (Dom f a b -> Cod f (f a) (f b)
forall a b. Dom f a b -> Cod f (f a) (f b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom f a b
Dom (Product f g) a b
f f a
m1) (Dom g a b -> Cod g (g a) (g b)
forall a b. Dom g a b -> Cod g (g a) (g b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom g a b
Dom (Product f g) a b
f g a
m2)

instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => CategoricalFunctor (Sum f g) where
  type Dom (Sum f g) = (->)
  type Cod (Sum f g) = (->)

  map :: forall a b.
Dom (Sum f g) a b -> Cod (Sum f g) (Sum f g a) (Sum f g b)
map Dom (Sum f g) a b
f (InL f a
m1) = f b -> Sum f g b
forall {k} (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
InL (f b -> Sum f g b) -> f b -> Sum f g b
forall a b. (a -> b) -> a -> b
$ Dom f a b -> Cod f (f a) (f b)
forall a b. Dom f a b -> Cod f (f a) (f b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom f a b
Dom (Sum f g) a b
f f a
m1
  map Dom (Sum f g) a b
f (InR g a
m2) = g b -> Sum f g b
forall {k} (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
InR (g b -> Sum f g b) -> g b -> Sum f g b
forall a b. (a -> b) -> a -> b
$ Dom g a b -> Cod g (g a) (g b)
forall a b. Dom g a b -> Cod g (g a) (g b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom g a b
Dom (Sum f g) a b
f g a
m2

instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => CategoricalFunctor (f :*: g) where
  type Dom (f :*: g) = (->)
  type Cod (f :*: g) = (->)

  map :: forall a b.
Dom (f :*: g) a b -> Cod (f :*: g) ((:*:) f g a) ((:*:) f g b)
map Dom (f :*: g) a b
f (f a
m1 :*: g a
m2) = Dom f a b -> Cod f (f a) (f b)
forall a b. Dom f a b -> Cod f (f a) (f b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom f a b
Dom (f :*: g) a b
f f a
m1 f b -> g b -> (:*:) f g b
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: Dom g a b -> Cod g (g a) (g b)
forall a b. Dom g a b -> Cod g (g a) (g b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom g a b
Dom (f :*: g) a b
f g a
m2

instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => CategoricalFunctor (f :+: g) where
  type Dom (f :+: g) = (->)
  type Cod (f :+: g) = (->)

  map :: forall a b.
Dom (f :+: g) a b -> Cod (f :+: g) ((:+:) f g a) ((:+:) f g b)
map Dom (f :+: g) a b
f (L1 f a
m1) = f b -> (:+:) f g b
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 (f b -> (:+:) f g b) -> f b -> (:+:) f g b
forall a b. (a -> b) -> a -> b
$ Dom f a b -> Cod f (f a) (f b)
forall a b. Dom f a b -> Cod f (f a) (f b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom f a b
Dom (f :+: g) a b
f f a
m1
  map Dom (f :+: g) a b
f (R1 g a
m2) = g b -> (:+:) f g b
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 (g b -> (:+:) f g b) -> g b -> (:+:) f g b
forall a b. (a -> b) -> a -> b
$ Dom g a b -> Cod g (g a) (g b)
forall a b. Dom g a b -> Cod g (g a) (g b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom g a b
Dom (f :+: g) a b
f g a
m2

deriving via (FromFunctor (K1 i c)) instance CategoricalFunctor (K1 i c :: Type -> Type)

deriving via (FromFunctor ((,,,) a b c)) instance CategoricalFunctor ((,,,) a b c)

deriving via (FromFunctor ((->) r)) instance CategoricalFunctor ((->) r)

instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => CategoricalFunctor (Compose f g) where
  type Dom (Compose f g) = (->)
  type Cod (Compose f g) = (->)

  map :: forall a b.
Dom (Compose f g) a b
-> Cod (Compose f g) (Compose f g a) (Compose f g b)
map Dom (Compose f g) a b
f (Compose f (g a)
fga) = f (g b) -> Compose f g b
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (f (g b) -> Compose f g b) -> f (g b) -> Compose f g b
forall a b. (a -> b) -> a -> b
$ Dom f (g a) (g b) -> Cod f (f (g a)) (f (g b))
forall a b. Dom f a b -> Cod f (f a) (f b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map (Dom g a b -> Cod g (g a) (g b)
forall a b. Dom g a b -> Cod g (g a) (g b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom g a b
Dom (Compose f g) a b
f) f (g a)
fga

instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => CategoricalFunctor (f :.: g) where
  type Dom (f :.: g) = (->)
  type Cod (f :.: g) = (->)

  map :: forall a b.
Dom (f :.: g) a b -> Cod (f :.: g) ((:.:) f g a) ((:.:) f g b)
map Dom (f :.: g) a b
f (Comp1 f (g a)
fga) = f (g b) -> (:.:) f g b
forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1).
f (g p) -> (:.:) f g p
Comp1 (f (g b) -> (:.:) f g b) -> f (g b) -> (:.:) f g b
forall a b. (a -> b) -> a -> b
$ Dom f (g a) (g b) -> Cod f (f (g a)) (f (g b))
forall a b. Dom f a b -> Cod f (f a) (f b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map (Dom g a b -> Cod g (g a) (g b)
forall a b. Dom g a b -> Cod g (g a) (g b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom g a b
Dom (f :.: g) a b
f) f (g a)
fga

instance (FunctorOf (->) (->) f) => CategoricalFunctor (M1 i c f) where
  type Dom (M1 i c f) = (->)
  type Cod (M1 i c f) = (->)

  map :: forall a b.
Dom (M1 i c f) a b -> Cod (M1 i c f) (M1 i c f a) (M1 i c f b)
map Dom (M1 i c f) a b
f (M1 f a
fp) = f b -> M1 i c f b
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (f b -> M1 i c f b) -> f b -> M1 i c f b
forall a b. (a -> b) -> a -> b
$ Dom f a b -> Cod f (f a) (f b)
forall a b. Dom f a b -> Cod f (f a) (f b)
forall from to (f :: from -> to) (a :: from) (b :: from).
CategoricalFunctor f =>
Dom f a b -> Cod f (f a) (f b)
map Dom f a b
Dom (M1 i c f) a b
f f a
fp

deriving via (FromFunctor ((,,,,) a b c d)) instance CategoricalFunctor ((,,,,) a b c d)

deriving via (FromFunctor ((,,,,,) a b c d e)) instance CategoricalFunctor ((,,,,,) a b c d e)

deriving via (FromFunctor ((,,,,,,) a b c d e f)) instance CategoricalFunctor ((,,,,,,) a b c d e f)

--------------------------------------------------------------------------------
-- Covariant MapArg1 instances

instance MapArg1 (->) ZipList

instance MapArg1 (->) Handler

instance MapArg1 (->) Complex

instance MapArg1 (->) Identity

instance MapArg1 (->) Monoid.First

instance MapArg1 (->) Monoid.Last

instance MapArg1 (->) Down

instance MapArg1 (->) Semigroup.First

instance MapArg1 (->) Semigroup.Last

instance MapArg1 (->) Semigroup.Max

instance MapArg1 (->) Semigroup.Min

instance MapArg1 (->) Semigroup.Dual

instance MapArg1 (->) Semigroup.Product

instance MapArg1 (->) Semigroup.Sum

instance MapArg1 (->) NonEmpty

instance MapArg1 (->) STM

instance MapArg1 (->) Par1

instance MapArg1 (->) ArgDescr

instance MapArg1 (->) ArgOrder

instance MapArg1 (->) OptDescr

instance MapArg1 (->) ReadP

instance MapArg1 (->) ReadPrec

instance MapArg1 (->) IO

instance MapArg1 (->) Maybe

instance MapArg1 (->) Solo

instance MapArg1 (->) []

instance (Monad m) => MapArg1 (->) (WrappedMonad m)

instance (Arrow a) => MapArg1 (->) (ArrowMonad a)

instance MapArg1 (->) (Lazy.ST s)

instance MapArg1 (->) (Either a)

instance MapArg1 (->) (Proxy :: Type -> Type)

instance MapArg1 (->) (Semigroup.Arg a)

instance MapArg1 (->) (Array i)

instance MapArg1 (->) (U1 :: Type -> Type)

instance MapArg1 (->) (V1 :: Type -> Type)

instance MapArg1 (->) (ST s)

instance MapArg1 (->) ((,) a)

instance (Arrow a) => MapArg1 (->) (WrappedArrow a b)

instance (FunctorOf (->) (->) m) => MapArg1 (->) (Kleisli m a)

instance MapArg1 (->) (Const m :: Type -> Type)

instance (FunctorOf (->) (->) f) => MapArg1 (->) (Monoid.Ap f)

instance (FunctorOf (->) (->) f) => MapArg1 (->) (Monoid.Alt f)

instance (FunctorOf (->) (->) f) => MapArg1 (->) (Rec1 f)

instance MapArg1 (->) (URec (Ptr ()) :: Type -> Type)

instance MapArg1 (->) (URec Char :: Type -> Type)

instance MapArg1 (->) (URec Double :: Type -> Type)

instance MapArg1 (->) (URec Float :: Type -> Type)

instance MapArg1 (->) (URec Int :: Type -> Type)

instance MapArg1 (->) (URec Word :: Type -> Type)

instance MapArg1 (->) ((,,) a b)

instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => MapArg1 (->) (Product f g)

instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => MapArg1 (->) (Sum f g)

instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => MapArg1 (->) (f :*: g)

instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => MapArg1 (->) (f :+: g)

instance MapArg1 (->) (K1 i c :: Type -> Type)

instance MapArg1 (->) ((,,,) a b c)

instance MapArg1 (->) ((->) r)

instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => MapArg1 (->) (Compose f g)

instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => MapArg1 (->) (f :.: g)

instance (FunctorOf (->) (->) f) => MapArg1 (->) (M1 i c f)

instance MapArg1 (->) ((,,,,) a b c d)

instance MapArg1 (->) ((,,,,,) a b c d e)

instance MapArg1 (->) ((,,,,,,) a b c d e f)

--------------------------------------------------------------------------------

newtype FromContra f a = FromContra (f a)
  deriving newtype ((forall a' a. (a' -> a) -> FromContra f a -> FromContra f a')
-> (forall b a. b -> FromContra f b -> FromContra f a)
-> Contravariant (FromContra f)
forall b a. b -> FromContra f b -> FromContra f a
forall a' a. (a' -> a) -> FromContra f a -> FromContra f a'
forall (f :: * -> *) b a.
Contravariant f =>
b -> FromContra f b -> FromContra f a
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> FromContra f a -> FromContra f a'
forall (f :: * -> *).
(forall a' a. (a' -> a) -> f a -> f a')
-> (forall b a. b -> f b -> f a) -> Contravariant f
$ccontramap :: forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> FromContra f a -> FromContra f a'
contramap :: forall a' a. (a' -> a) -> FromContra f a -> FromContra f a'
$c>$ :: forall (f :: * -> *) b a.
Contravariant f =>
b -> FromContra f b -> FromContra f a
>$ :: forall b a. b -> FromContra f b -> FromContra f a
Hask.Contravariant)

instance (Hask.Contravariant f) => CategoricalFunctor (FromContra f) where
  type Dom (FromContra f) = Op
  type Cod (FromContra f) = (->)

  map :: Dom (FromContra f) a b -> Cod (FromContra f) ((FromContra f) a) ((FromContra f) b)
  map :: forall a b.
Dom (FromContra f) a b
-> Cod (FromContra f) (FromContra f a) (FromContra f b)
map = (b -> a) -> FromContra f a -> FromContra f b
forall a' a. (a' -> a) -> FromContra f a -> FromContra f a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
Hask.contramap ((b -> a) -> FromContra f a -> FromContra f b)
-> (Op a b -> b -> a) -> Op a b -> FromContra f a -> FromContra f b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Op a b -> b -> a
forall a b. Op a b -> b -> a
getOp

--------------------------------------------------------------------------------
-- Contravariant Functor instances

deriving via (FromContra Predicate) instance CategoricalFunctor Predicate

-- TODO: Add remaining Contravariant instances

--------------------------------------------------------------------------------
-- Contravariant MapArg1 instances

instance MapArg1 Op Predicate

-- TODO: Add remaining Contravariant instances

--------------------------------------------------------------------------------

instance CategoricalFunctor Monoid.Endo where
  type Dom Monoid.Endo = (<->)
  type Cod Monoid.Endo = (->)

  map :: (a <-> b) -> Monoid.Endo a -> Monoid.Endo b
  map :: forall a b. (a <-> b) -> Endo a -> Endo b
map Iso {a -> b
b -> a
fwd :: a -> b
bwd :: b -> a
fwd :: forall {k} (cat :: k -> k -> *) (a :: k) (b :: k).
Iso cat a b -> cat a b
bwd :: forall {k} (cat :: k -> k -> *) (a :: k) (b :: k).
Iso cat a b -> cat b a
..} (Monoid.Endo a -> a
f) = (b -> b) -> Endo b
forall a. (a -> a) -> Endo a
Monoid.Endo (a -> b
fwd (a -> b) -> (b -> a) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> a
f (a -> a) -> (b -> a) -> b -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. b -> a
bwd)

instance MapArg1 (<->) Monoid.Endo

--------------------------------------------------------------------------------

newtype FromFilterable f a = FromFilterable (f a)
  deriving newtype ((forall a b. (a -> b) -> FromFilterable f a -> FromFilterable f b)
-> (forall a b. a -> FromFilterable f b -> FromFilterable f a)
-> Functor (FromFilterable f)
forall a b. a -> FromFilterable f b -> FromFilterable f a
forall a b. (a -> b) -> FromFilterable f a -> FromFilterable f b
forall (f :: * -> *) a b.
Functor f =>
a -> FromFilterable f b -> FromFilterable f a
forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> FromFilterable f a -> FromFilterable f b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> FromFilterable f a -> FromFilterable f b
fmap :: forall a b. (a -> b) -> FromFilterable f a -> FromFilterable f b
$c<$ :: forall (f :: * -> *) a b.
Functor f =>
a -> FromFilterable f b -> FromFilterable f a
<$ :: forall a b. a -> FromFilterable f b -> FromFilterable f a
Hask.Functor, Functor (FromFilterable f)
Functor (FromFilterable f) =>
(forall a b.
 (a -> Maybe b) -> FromFilterable f a -> FromFilterable f b)
-> (forall a. FromFilterable f (Maybe a) -> FromFilterable f a)
-> (forall a.
    (a -> Bool) -> FromFilterable f a -> FromFilterable f a)
-> Filterable (FromFilterable f)
forall a. FromFilterable f (Maybe a) -> FromFilterable f a
forall a. (a -> Bool) -> FromFilterable f a -> FromFilterable f a
forall a b.
(a -> Maybe b) -> FromFilterable f a -> FromFilterable f b
forall (f :: * -> *).
Functor f =>
(forall a b. (a -> Maybe b) -> f a -> f b)
-> (forall a. f (Maybe a) -> f a)
-> (forall a. (a -> Bool) -> f a -> f a)
-> Filterable f
forall (f :: * -> *). Filterable f => Functor (FromFilterable f)
forall (f :: * -> *) a.
Filterable f =>
FromFilterable f (Maybe a) -> FromFilterable f a
forall (f :: * -> *) a.
Filterable f =>
(a -> Bool) -> FromFilterable f a -> FromFilterable f a
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> FromFilterable f a -> FromFilterable f b
$cmapMaybe :: forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> FromFilterable f a -> FromFilterable f b
mapMaybe :: forall a b.
(a -> Maybe b) -> FromFilterable f a -> FromFilterable f b
$ccatMaybes :: forall (f :: * -> *) a.
Filterable f =>
FromFilterable f (Maybe a) -> FromFilterable f a
catMaybes :: forall a. FromFilterable f (Maybe a) -> FromFilterable f a
$cfilter :: forall (f :: * -> *) a.
Filterable f =>
(a -> Bool) -> FromFilterable f a -> FromFilterable f a
filter :: forall a. (a -> Bool) -> FromFilterable f a -> FromFilterable f a
Hask.Filterable)

instance (Hask.Filterable f) => CategoricalFunctor (FromFilterable f) where
  type Dom (FromFilterable f) = (Hask.Profunctor.Star Maybe)
  type Cod (FromFilterable f) = (->)

  map :: Hask.Profunctor.Star Maybe a b -> FromFilterable f a -> FromFilterable f b
  map :: forall a b.
Star Maybe a b -> FromFilterable f a -> FromFilterable f b
map (Hask.Profunctor.Star a -> Maybe b
f) (FromFilterable f a
fa) = f b -> FromFilterable f b
forall {k} (f :: k -> *) (a :: k). f a -> FromFilterable f a
FromFilterable ((a -> Maybe b) -> f a -> f b
forall a b. (a -> Maybe b) -> f a -> f b
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
Hask.mapMaybe a -> Maybe b
f f a
fa)

--------------------------------------------------------------------------------

-- NOTE: These instances conflict with our Covariant Functor
-- instances. Switching from associated types to Multi Parameter type
-- classes would fix this:

-- deriving via (FromFilterable []) instance Functor []

-- deriving via (FromFilterable Maybe) instance Functor Maybe