kindly-functors-0.2.0.0: src/Kindly/Functor.hs
{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -Wno-orphans #-}
-- | Single Parameter Functors of arbitrary categories.
module Kindly.Functor
( Functor,
fmap,
contramap,
mapIso,
invmap,
Iso (..),
Filterable,
mapMaybe,
catMaybes,
filter,
FromFunctor (..),
FromContra (..),
)
where
--------------------------------------------------------------------------------
import Control.Applicative (Const, WrappedArrow, WrappedMonad, ZipList)
import Control.Applicative.Backwards (Backwards (..))
import Control.Applicative.Lift (Lift (..))
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 Control.Monad.Trans.Accum (AccumT (..))
import Control.Monad.Trans.Cont (ContT (..))
import Control.Monad.Trans.Except (ExceptT (..))
import Control.Monad.Trans.Identity (IdentityT (..))
import Control.Monad.Trans.Maybe (MaybeT (..))
import Control.Monad.Trans.RWS.CPS qualified as CPS
import Control.Monad.Trans.RWS.Lazy qualified as Lazy
import Control.Monad.Trans.RWS.Strict qualified as Strict
import Control.Monad.Trans.Reader (ReaderT (..))
import Control.Monad.Trans.Select (SelectT (..))
import Control.Monad.Trans.State.Lazy qualified as Lazy
import Control.Monad.Trans.State.Strict qualified as Strict
import Control.Monad.Trans.Writer.CPS qualified as CPS
import Control.Monad.Trans.Writer.Lazy qualified as Lazy
import Control.Monad.Trans.Writer.Strict qualified as Strict
import Data.Bifunctor.Biff (Biff (..))
import Data.Bifunctor.Clown (Clown (..))
import Data.Bifunctor.Fix (Fix (..))
import Data.Bifunctor.Flip (Flip (..))
import Data.Bifunctor.Joker (Joker (..))
import Data.Bifunctor.Product qualified as Bifunctor
import Data.Bifunctor.Sum qualified as Bifunctor
import Data.Bifunctor.Tannen (Tannen (..))
import Data.Bifunctor.Wrapped (WrappedBifunctor (..))
import Data.Complex (Complex)
import Data.Either (Either (..))
import Data.Functor qualified as Hask
import Data.Functor.Apply (MaybeApply (..), WrappedApplicative (..))
import Data.Functor.Compose (Compose (..))
import Data.Functor.Constant (Constant)
import Data.Functor.Contravariant (Comparison, Equivalence, Op (..), Predicate)
import Data.Functor.Contravariant qualified as Hask
import Data.Functor.Identity (Identity (..))
import Data.Functor.Product (Product (..))
import Data.Functor.Reverse (Reverse (..))
import Data.Functor.Sum (Sum (..))
import Data.Functor.These (These1 (..))
import Data.Graph (SCC)
import Data.IntMap (IntMap)
import Data.Isomorphism
import Data.Kind (Constraint, Type)
import Data.List.NonEmpty (NonEmpty)
import Data.Map (Map)
import Data.Maybe (Maybe (..))
import Data.Monoid qualified as Monoid
import Data.Ord (Down)
import Data.Profunctor qualified as Hask.Profunctor
import Data.Profunctor.Cayley qualified as Hask.Profunctor
import Data.Profunctor.Choice qualified as Hask.Profunctor
import Data.Profunctor.Closed qualified as Hask.Profunctor
import Data.Profunctor.Composition qualified as Hask.Profunctor
import Data.Profunctor.Mapping qualified as Hask.Profunctor
import Data.Profunctor.Strong qualified as Hask.Profunctor
import Data.Profunctor.Traversing qualified as Hask.Profunctor
import Data.Profunctor.Yoneda qualified as Hask.Profunctor
import Data.Proxy (Proxy)
import Data.Semigroup qualified as Semigroup
import Data.Semigroupoid.Dual (Dual (..))
import Data.Semigroupoid.Static (Static (..))
import Data.Sequence (Seq, ViewL, ViewR)
import Data.Tagged (Tagged)
import Data.These (These)
import Data.Tree (Tree)
#if MIN_VERSION_base(4,16,0)
import Data.Tuple (Solo)
#endif
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, (:*:) (..), (:+:) (..), (:.:) (..))
#if MIN_VERSION_base(4,17,0)
import GHC.Generics (Generic1, Generically1, Rep1)
#endif
import Kindly.Class
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 = 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 t'Op'.
contramap :: (Functor Op p) => (a -> b) -> p b -> p a
contramap = fmap . Op
-- | Map a @('->')@ isomorphism through a 'Functor' of /any/ variance. A functor
-- can always transport an isomorphism. 'liftIso' reflects the iso into the
-- functor's domain category @cat@, dropping whichever leg @cat@ ignores (the
-- backward leg for a covariant @('->')@ functor, the forward leg for a
-- contravariant 'Op' one, neither for an invariant @'Iso' ('->')@ one).
--
-- 'mapIso' generalizes 'invmap'. @'invmap' f g = 'mapIso' ('Iso' f g)@.
mapIso :: (Functor cat f, LiftIso cat) => Iso (->) a b -> f a -> f b
mapIso i = fmap (liftIso i)
-- | Map an isomorphism through a 'Functor' of /any/ variance, generalizing the
-- invariant-only version. The two legs are packed into an @'Iso' ('->')@ and
-- mapped with 'mapIso', so 'invmap' now resolves for covariant and
-- contravariant functors too, not just invariant ones. The domain category is
-- fixed by the functor argument, so existing invariant call sites are
-- unaffected.
invmap :: (Functor cat f, LiftIso cat) => (a -> b) -> (b -> a) -> f a -> f b
invmap f g = mapIso (Iso f 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 f = map (Hask.Profunctor.Star 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 = map (Hask.Profunctor.Star 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 f = map (Hask.Profunctor.Star (\a -> if f a then Just a else Nothing))
--------------------------------------------------------------------------------
-- | A @DerivingVia@ adapter: give any base @Functor@ a covariant
-- 'CategoricalFunctor' instance (@Dom = (->)@, @Cod = (->)@).
--
-- > deriving via (FromFunctor MyType) instance CategoricalFunctor MyType
newtype FromFunctor f a = FromFunctor (f a)
deriving newtype (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 = 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
#if MIN_VERSION_base(4,16,0)
deriving via (FromFunctor Solo) instance CategoricalFunctor Solo
#endif
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 f (Kleisli m) = Kleisli $ \a -> map f (m 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 f (Monoid.Ap m) = Monoid.Ap $ map f m
instance (FunctorOf (->) (->) f) => CategoricalFunctor (Monoid.Alt f) where
type Dom (Monoid.Alt f) = (->)
type Cod (Monoid.Alt f) = (->)
map f (Monoid.Alt m) = Monoid.Alt $ map f m
instance (FunctorOf (->) (->) f) => CategoricalFunctor (Rec1 f) where
type Dom (Rec1 f) = (->)
type Cod (Rec1 f) = (->)
map f (Rec1 m) = Rec1 $ map f 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 f (Pair m1 m2) = Pair (map f m1) (map f m2)
instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => CategoricalFunctor (Sum f g) where
type Dom (Sum f g) = (->)
type Cod (Sum f g) = (->)
map f (InL m1) = InL $ map f m1
map f (InR m2) = InR $ map f m2
instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => CategoricalFunctor (f :*: g) where
type Dom (f :*: g) = (->)
type Cod (f :*: g) = (->)
map f (m1 :*: m2) = map f m1 :*: map f m2
instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => CategoricalFunctor (f :+: g) where
type Dom (f :+: g) = (->)
type Cod (f :+: g) = (->)
map f (L1 m1) = L1 $ map f m1
map f (R1 m2) = R1 $ map f 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 f (Compose fga) = Compose $ map (map f) fga
instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => CategoricalFunctor (f :.: g) where
type Dom (f :.: g) = (->)
type Cod (f :.: g) = (->)
map f (Comp1 fga) = Comp1 $ map (map f) fga
instance (FunctorOf (->) (->) f) => CategoricalFunctor (M1 i c f) where
type Dom (M1 i c f) = (->)
type Cod (M1 i c f) = (->)
map f (M1 fp) = M1 $ map f 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)
#if MIN_VERSION_base(4,17,0)
deriving via (FromFunctor (Generically1 (f :: Type -> Type))) instance (Generic1 f, Hask.Functor (Rep1 f)) => CategoricalFunctor (Generically1 f)
#endif
instance (FunctorOf (->) (->) m) => CategoricalFunctor (IdentityT m) where
type Dom (IdentityT m) = (->)
type Cod (IdentityT m) = (->)
map f (IdentityT m) = IdentityT $ map f m
instance (FunctorOf (->) (->) m) => CategoricalFunctor (MaybeT m) where
type Dom (MaybeT m) = (->)
type Cod (MaybeT m) = (->)
map f (MaybeT m) = MaybeT $ map (map f) m
instance (FunctorOf (->) (->) m) => CategoricalFunctor (ExceptT e m) where
type Dom (ExceptT e m) = (->)
type Cod (ExceptT e m) = (->)
map f (ExceptT m) = ExceptT $ map (map f) m
instance (FunctorOf (->) (->) m) => CategoricalFunctor (ReaderT r m) where
type Dom (ReaderT r m) = (->)
type Cod (ReaderT r m) = (->)
map f (ReaderT g) = ReaderT $ \r -> map f (g r)
instance (FunctorOf (->) (->) m) => CategoricalFunctor (Lazy.StateT s m) where
type Dom (Lazy.StateT s m) = (->)
type Cod (Lazy.StateT s m) = (->)
map f (Lazy.StateT g) = Lazy.StateT $ \s -> map (\(a, s') -> (f a, s')) (g s)
instance (FunctorOf (->) (->) m) => CategoricalFunctor (Strict.StateT s m) where
type Dom (Strict.StateT s m) = (->)
type Cod (Strict.StateT s m) = (->)
map f (Strict.StateT g) = Strict.StateT $ \s -> map (\(a, s') -> (f a, s')) (g s)
instance (FunctorOf (->) (->) m) => CategoricalFunctor (Lazy.WriterT w m) where
type Dom (Lazy.WriterT w m) = (->)
type Cod (Lazy.WriterT w m) = (->)
map f (Lazy.WriterT m) = Lazy.WriterT $ map (\(a, w) -> (f a, w)) m
instance (FunctorOf (->) (->) m) => CategoricalFunctor (Strict.WriterT w m) where
type Dom (Strict.WriterT w m) = (->)
type Cod (Strict.WriterT w m) = (->)
map f (Strict.WriterT m) = Strict.WriterT $ map (\(a, w) -> (f a, w)) m
deriving via (FromFunctor (CPS.WriterT w m)) instance (Hask.Functor m) => CategoricalFunctor (CPS.WriterT w m)
instance CategoricalFunctor (ContT r m) where
type Dom (ContT r m) = (->)
type Cod (ContT r m) = (->)
map f (ContT g) = ContT $ \k -> g (k . f)
instance (FunctorOf (->) (->) m) => CategoricalFunctor (Lazy.RWST r w s m) where
type Dom (Lazy.RWST r w s m) = (->)
type Cod (Lazy.RWST r w s m) = (->)
map f (Lazy.RWST g) = Lazy.RWST $ \r s -> map (\(a, s', w) -> (f a, s', w)) (g r s)
instance (FunctorOf (->) (->) m) => CategoricalFunctor (Strict.RWST r w s m) where
type Dom (Strict.RWST r w s m) = (->)
type Cod (Strict.RWST r w s m) = (->)
map f (Strict.RWST g) = Strict.RWST $ \r s -> map (\(a, s', w) -> (f a, s', w)) (g r s)
deriving via (FromFunctor (CPS.RWST r w s m)) instance (Hask.Functor m) => CategoricalFunctor (CPS.RWST r w s m)
instance (FunctorOf (->) (->) m) => CategoricalFunctor (AccumT w m) where
type Dom (AccumT w m) = (->)
type Cod (AccumT w m) = (->)
map f (AccumT g) = AccumT $ \w -> map (\(a, w') -> (f a, w')) (g w)
instance (FunctorOf (->) (->) m) => CategoricalFunctor (SelectT r m) where
type Dom (SelectT r m) = (->)
type Cod (SelectT r m) = (->)
map f (SelectT g) = SelectT $ \k -> map f (g (k . f))
instance (FunctorOf (->) (->) f) => CategoricalFunctor (Backwards f) where
type Dom (Backwards f) = (->)
type Cod (Backwards f) = (->)
map f (Backwards m) = Backwards $ map f m
instance (FunctorOf (->) (->) f) => CategoricalFunctor (Reverse f) where
type Dom (Reverse f) = (->)
type Cod (Reverse f) = (->)
map f (Reverse m) = Reverse $ map f m
deriving via (FromFunctor (Constant a)) instance CategoricalFunctor (Constant a :: Type -> Type)
instance (FunctorOf (->) (->) f) => CategoricalFunctor (Lift f) where
type Dom (Lift f) = (->)
type Cod (Lift f) = (->)
map f (Pure a) = Pure $ f a
map f (Other m) = Other $ map f m
instance (FunctorOf (->) (->) f) => CategoricalFunctor (Hask.Profunctor.Star f a) where
type Dom (Hask.Profunctor.Star f a) = (->)
type Cod (Hask.Profunctor.Star f a) = (->)
map f (Hask.Profunctor.Star g) = Hask.Profunctor.Star $ \x -> map f (g x)
deriving via (FromFunctor (Hask.Profunctor.Costar f a)) instance CategoricalFunctor (Hask.Profunctor.Costar f a)
deriving via (FromFunctor (Hask.Profunctor.Forget r a)) instance CategoricalFunctor (Hask.Profunctor.Forget r a :: Type -> Type)
instance (FunctorOf (->) (->) f) => CategoricalFunctor (WrappedApplicative f) where
type Dom (WrappedApplicative f) = (->)
type Cod (WrappedApplicative f) = (->)
map f (WrapApplicative m) = WrapApplicative $ map f m
instance (FunctorOf (->) (->) f) => CategoricalFunctor (MaybeApply f) where
type Dom (MaybeApply f) = (->)
type Cod (MaybeApply f) = (->)
map f (MaybeApply (Left fa)) = MaybeApply $ Left $ map f fa
map f (MaybeApply (Right a)) = MaybeApply $ Right $ f a
instance (FunctorOf (->) (->) f) => CategoricalFunctor (Static f a) where
type Dom (Static f a) = (->)
type Cod (Static f a) = (->)
map f (Static g) = Static $ map (f .) g
instance (FunctorOf (->) (->) f, FunctorOf (->) (->) g) => CategoricalFunctor (These1 f g) where
type Dom (These1 f g) = (->)
type Cod (These1 f g) = (->)
map f (This1 fa) = This1 $ map f fa
map f (That1 ga) = That1 $ map f ga
map f (These1 fa ga) = These1 (map f fa) (map f ga)
instance (MapArg2 (->) (->) p) => CategoricalFunctor (Flip p a) where
type Dom (Flip p a) = (->)
type Cod (Flip p a) = (->)
map f (Flip pba) = Flip $ map2 f pba
deriving via (FromFunctor (Clown f a)) instance CategoricalFunctor (Clown f a :: Type -> Type)
instance (FunctorOf (->) (->) g) => CategoricalFunctor (Joker g a) where
type Dom (Joker g a) = (->)
type Cod (Joker g a) = (->)
map f (Joker gb) = Joker $ map f gb
instance (FunctorOf (->) (->) (p a), FunctorOf (->) (->) (q a)) => CategoricalFunctor (Bifunctor.Product p q a) where
type Dom (Bifunctor.Product p q a) = (->)
type Cod (Bifunctor.Product p q a) = (->)
map f (Bifunctor.Pair pab qab) = Bifunctor.Pair (map f pab) (map f qab)
instance (FunctorOf (->) (->) (p a), FunctorOf (->) (->) (q a)) => CategoricalFunctor (Bifunctor.Sum p q a) where
type Dom (Bifunctor.Sum p q a) = (->)
type Cod (Bifunctor.Sum p q a) = (->)
map f (Bifunctor.L2 pab) = Bifunctor.L2 $ map f pab
map f (Bifunctor.R2 qab) = Bifunctor.R2 $ map f qab
instance (FunctorOf (->) (->) f, FunctorOf (->) (->) (p a)) => CategoricalFunctor (Tannen f p a) where
type Dom (Tannen f p a) = (->)
type Cod (Tannen f p a) = (->)
map g (Tannen fp) = Tannen $ map (map g) fp
instance (FunctorOf (->) (->) (p (f a)), FunctorOf (->) (->) g) => CategoricalFunctor (Biff p f g a) where
type Dom (Biff p f g a) = (->)
type Cod (Biff p f g a) = (->)
map h (Biff pfg) = Biff $ map (map h) pfg
instance (FunctorOf (->) (->) (p a)) => CategoricalFunctor (WrappedBifunctor p a) where
type Dom (WrappedBifunctor p a) = (->)
type Cod (WrappedBifunctor p a) = (->)
map f (WrapBifunctor pab) = WrapBifunctor $ map f pab
instance (forall x. MapArg1 (->) (p x)) => CategoricalFunctor (Hask.Profunctor.Procompose p q a) where
type Dom (Hask.Profunctor.Procompose p q a) = (->)
type Cod (Hask.Profunctor.Procompose p q a) = (->)
map f (Hask.Profunctor.Procompose pxc qdx) = Hask.Profunctor.Procompose (map1 f pxc) qdx
instance (MapArg2 Op (->) p) => CategoricalFunctor (Hask.Profunctor.Rift p q a) where
type Dom (Hask.Profunctor.Rift p q a) = (->)
type Cod (Hask.Profunctor.Rift p q a) = (->)
map f (Hask.Profunctor.Rift g) = Hask.Profunctor.Rift $ \p -> g (map2 (Op f) p)
instance CategoricalFunctor (Hask.Profunctor.Yoneda p a) where
type Dom (Hask.Profunctor.Yoneda p a) = (->)
type Cod (Hask.Profunctor.Yoneda p a) = (->)
map f (Hask.Profunctor.Yoneda g) = Hask.Profunctor.Yoneda $ \l r -> g l (r . f)
instance CategoricalFunctor (Hask.Profunctor.Coyoneda p a) where
type Dom (Hask.Profunctor.Coyoneda p a) = (->)
type Cod (Hask.Profunctor.Coyoneda p a) = (->)
map f (Hask.Profunctor.Coyoneda l r p) = Hask.Profunctor.Coyoneda l (f . r) p
instance (FunctorOf (->) (->) f, FunctorOf (->) (->) (p a)) => CategoricalFunctor (Hask.Profunctor.Cayley f p a) where
type Dom (Hask.Profunctor.Cayley f p a) = (->)
type Cod (Hask.Profunctor.Cayley f p a) = (->)
map g (Hask.Profunctor.Cayley fp) = Hask.Profunctor.Cayley $ map (map g) fp
instance (forall x. MapArg1 (->) (p x)) => CategoricalFunctor (Hask.Profunctor.Tambara p a) where
type Dom (Hask.Profunctor.Tambara p a) = (->)
type Cod (Hask.Profunctor.Tambara p a) = (->)
map f (Hask.Profunctor.Tambara t) = Hask.Profunctor.Tambara $ map1 (\(b, c) -> (f b, c)) t
instance CategoricalFunctor (Hask.Profunctor.Pastro p a) where
type Dom (Hask.Profunctor.Pastro p a) = (->)
type Cod (Hask.Profunctor.Pastro p a) = (->)
map f (Hask.Profunctor.Pastro l m r) = Hask.Profunctor.Pastro (f . l) m r
instance CategoricalFunctor (Hask.Profunctor.Cotambara q a) where
type Dom (Hask.Profunctor.Cotambara q a) = (->)
type Cod (Hask.Profunctor.Cotambara q a) = (->)
map f (Hask.Profunctor.Cotambara n r) = Hask.Profunctor.Cotambara n (Hask.Profunctor.rmap f r)
instance CategoricalFunctor (Hask.Profunctor.Copastro p a) where
type Dom (Hask.Profunctor.Copastro p a) = (->)
type Cod (Hask.Profunctor.Copastro p a) = (->)
map f (Hask.Profunctor.Copastro g) = Hask.Profunctor.Copastro $ \n -> Hask.Profunctor.rmap f (g n)
instance (forall x. MapArg1 (->) (p x)) => CategoricalFunctor (Hask.Profunctor.TambaraSum p a) where
type Dom (Hask.Profunctor.TambaraSum p a) = (->)
type Cod (Hask.Profunctor.TambaraSum p a) = (->)
map f (Hask.Profunctor.TambaraSum t) =
Hask.Profunctor.TambaraSum $ map1 (\case Left b -> Left (f b); Right c -> Right c) t
instance CategoricalFunctor (Hask.Profunctor.PastroSum p a) where
type Dom (Hask.Profunctor.PastroSum p a) = (->)
type Cod (Hask.Profunctor.PastroSum p a) = (->)
map f (Hask.Profunctor.PastroSum l m r) = Hask.Profunctor.PastroSum (f . l) m r
instance CategoricalFunctor (Hask.Profunctor.CotambaraSum q a) where
type Dom (Hask.Profunctor.CotambaraSum q a) = (->)
type Cod (Hask.Profunctor.CotambaraSum q a) = (->)
map f (Hask.Profunctor.CotambaraSum n r) = Hask.Profunctor.CotambaraSum n (Hask.Profunctor.rmap f r)
instance CategoricalFunctor (Hask.Profunctor.CopastroSum p a) where
type Dom (Hask.Profunctor.CopastroSum p a) = (->)
type Cod (Hask.Profunctor.CopastroSum p a) = (->)
map f (Hask.Profunctor.CopastroSum g) = Hask.Profunctor.CopastroSum $ \n -> Hask.Profunctor.rmap f (g n)
instance (forall x. MapArg1 (->) (p x)) => CategoricalFunctor (Hask.Profunctor.Closure p a) where
type Dom (Hask.Profunctor.Closure p a) = (->)
type Cod (Hask.Profunctor.Closure p a) = (->)
map f (Hask.Profunctor.Closure t) = Hask.Profunctor.Closure $ map1 (f .) t
instance CategoricalFunctor (Hask.Profunctor.Environment p a) where
type Dom (Hask.Profunctor.Environment p a) = (->)
type Cod (Hask.Profunctor.Environment p a) = (->)
map f (Hask.Profunctor.Environment l m r) = Hask.Profunctor.Environment (f . l) m r
instance CategoricalFunctor (Hask.Profunctor.FreeTraversing p a) where
type Dom (Hask.Profunctor.FreeTraversing p a) = (->)
type Cod (Hask.Profunctor.FreeTraversing p a) = (->)
map f (Hask.Profunctor.FreeTraversing l m r) = Hask.Profunctor.FreeTraversing (f . l) m r
instance (forall x. MapArg1 (->) (p x)) => CategoricalFunctor (Hask.Profunctor.CofreeTraversing p a) where
type Dom (Hask.Profunctor.CofreeTraversing p a) = (->)
type Cod (Hask.Profunctor.CofreeTraversing p a) = (->)
map f (Hask.Profunctor.CofreeTraversing t) = Hask.Profunctor.CofreeTraversing $ map1 (Hask.fmap f) t
instance CategoricalFunctor (Hask.Profunctor.FreeMapping p a) where
type Dom (Hask.Profunctor.FreeMapping p a) = (->)
type Cod (Hask.Profunctor.FreeMapping p a) = (->)
map f (Hask.Profunctor.FreeMapping l m r) = Hask.Profunctor.FreeMapping (f . l) m r
instance (forall x. MapArg1 (->) (p x)) => CategoricalFunctor (Hask.Profunctor.CofreeMapping p a) where
type Dom (Hask.Profunctor.CofreeMapping p a) = (->)
type Cod (Hask.Profunctor.CofreeMapping p a) = (->)
map f (Hask.Profunctor.CofreeMapping t) = Hask.Profunctor.CofreeMapping $ map1 (Hask.fmap f) t
deriving via (FromFunctor (Tagged s)) instance CategoricalFunctor (Tagged s)
instance (MapArg2 (->) (->) p) => CategoricalFunctor (Fix p) where
type Dom (Fix p) = (->)
type Cod (Fix p) = (->)
map f (In p) = In (map2 (map f) (map1 f p))
deriving via (FromFunctor (Map k)) instance CategoricalFunctor (Map k)
deriving via (FromFunctor IntMap) instance CategoricalFunctor IntMap
deriving via (FromFunctor Seq) instance CategoricalFunctor Seq
deriving via (FromFunctor ViewL) instance CategoricalFunctor ViewL
deriving via (FromFunctor ViewR) instance CategoricalFunctor ViewR
deriving via (FromFunctor Tree) instance CategoricalFunctor Tree
deriving via (FromFunctor SCC) instance CategoricalFunctor SCC
--------------------------------------------------------------------------------
-- | A @DerivingVia@ adapter: give any base @Contravariant@ a contravariant
-- 'CategoricalFunctor' instance (@Dom = Op@).
--
-- > deriving via (FromContra MyType) instance CategoricalFunctor MyType
newtype FromContra f a = FromContra (f a)
deriving newtype (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 = Hask.contramap . getOp
--------------------------------------------------------------------------------
-- Contravariant Functor instances
deriving via (FromContra Predicate) instance CategoricalFunctor Predicate
deriving via (FromContra Comparison) instance CategoricalFunctor Comparison
deriving via (FromContra Equivalence) instance CategoricalFunctor Equivalence
deriving via (FromContra (Op a)) instance CategoricalFunctor (Op a)
instance (MapArg2 Op (->) k) => CategoricalFunctor (Dual k a) where
type Dom (Dual k a) = Op
type Cod (Dual k a) = (->)
map (Op f) (Dual kba) = Dual (map2 (Op f) kba)
--------------------------------------------------------------------------------
instance CategoricalFunctor Monoid.Endo where
type Dom Monoid.Endo = Iso (->)
type Cod Monoid.Endo = (->)
map :: Iso (->) a b -> Monoid.Endo a -> Monoid.Endo b
map Iso {..} (Monoid.Endo f) = Monoid.Endo (embed . f . project)
--------------------------------------------------------------------------------
newtype FromFilterable f a = FromFilterable (f a)
deriving newtype (Hask.Functor, 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 (Hask.Profunctor.Star f) (FromFilterable fa) = FromFilterable (Hask.mapMaybe f 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