module Pandora.Pattern.Functor.Bivariant where

import Pandora.Pattern.Category (($))

infixl 4 <->

{- |
> When providing a new instance, you should ensure it satisfies the two laws:
> * Identity: bimap identity identity ≡ identity
> * Parametricity: bimap  (f . g) (h . i) ≡ bimap f h . bimap g i
-}

class Bivariant (v :: * -> * -> *) where
	{-# MINIMAL (<->) #-}
	(<->) :: (a -> b) -> (c -> d) -> v a c -> v b d
	-- | Prefix version of '<->'
	bimap :: (a -> b) -> (c -> d) -> v a c -> v b d
	bimap a -> b
f c -> d
g v a c
x = a -> b
f (a -> b) -> (c -> d) -> v a c -> v b d
forall (v :: * -> * -> *) a b c d.
Bivariant v =>
(a -> b) -> (c -> d) -> v a c -> v b d
<-> c -> d
g (v a c -> v b d) -> v a c -> v b d
forall (m :: * -> * -> *) a b. Category m => m a b -> m a b
$ v a c
x