module Pandora.Pattern.Functor.Invariant where

{- |
> When providing a new instance, you should ensure it satisfies:
> Identity morphisms: invmap identity identity = identity
> Interpreted of morphisms: invmap g j . invmap f h = invmap (g . f) (h . j)
-}

infixl 4 <$<

class Invariant (t :: * -> *) where
	{-# MINIMAL (<$<) #-}
	(<$<) :: (a -> b) -> (b -> a) -> t a -> t b
	-- | Prefix version of '<$<'
	invmap :: (a -> b) -> (b -> a) -> t a -> t b
	invmap a -> b
f b -> a
g t a
x = (a -> b
f (a -> b) -> (b -> a) -> t a -> t b
forall (t :: * -> *) a b.
Invariant t =>
(a -> b) -> (b -> a) -> t a -> t b
<$< b -> a
g) t a
x