pandora-0.4.7: Pandora/Pattern/Functor/Covariant.hs
{-# LANGUAGE AllowAmbiguousTypes #-}
module Pandora.Pattern.Functor.Covariant where
import Pandora.Pattern.Semigroupoid (Semigroupoid)
infixl 4 <$>
infixl 3 <$$>
infixl 4 <$$$>
{- |
> When providing a new instance, you should ensure it satisfies:
> * Identity morphism: (identity <$>) ≡ identity
> * Interpreted of morphisms: (f . g <$>) ≡ (f <$>) . (g <$>)
-}
class (Semigroupoid source, Semigroupoid target) => Covariant source target t where
(<$>) :: source a b -> target (t a) (t b)
(<$$>) :: forall source between target t u a b
. (Covariant source between u, Covariant between target t)
=> source a b -> target (t (u a)) (t (u b))
(<$$>) s = ((<$>) ((<$>) @source @between @u s))
(<$$$>) :: forall source between1 between2 target t u v a b
. (Covariant source between1 v, Covariant between1 between2 u, Covariant between2 target t)
=> source a b -> target (t (u (v a))) (t (u (v b)))
(<$$$>) s = ((<$>) @between2 @target ((<$>) @between1 @between2 @u ((<$>) @source @between1 @v s)))
(<$$$$>) :: forall source between1 between2 between3 target t u v w a b
. (Covariant source between1 w, Covariant between1 between2 v, Covariant between2 between3 u, Covariant between3 target t)
=> source a b -> target (t (u (v (w a)))) (t (u (v (w b))))
(<$$$$>) s = ((<$>) @between3 @target @t ((<$>) @between2 @between3 @u ((<$>) @between1 @between2 @v ((<$>) @source @between1 @w s))))