ekmett/contravariant

Add Bicontravariant

treeowl opened this issue · 0 comments

A Getter in mezzolens uses an OutPhantom constraint, which can be seen as a Bicontravariant Profunctor. But the former doesn't seem to exist!

class Bicontravariant p where
  bicontramap :: (a' -> a) -> (b' -> b) -> p a b -> p a' b'
  lcmap :: (a' -> a) -> p a b -> p a' b
  rcmap :: (b' -> b) -> p a b -> p a b'

class (Profunctor p, Bicontravariant p) => OutPhantom p where
  ocoerce :: p a b -> p a b'
  ocoerce = rmap absurd . rcmap absurd

  ocoerceLmap :: (a' -> a) -> p a b -> p a' b'
  ocoerceLmap f = dimap f absurd . rcmap absurd

The other side is similar:

class (Profunctor p, Bifunctor p) => InPhantom p where
  icoerce :: p a b -> p a' b
  icoerce = first absurd . lmap absurd

  icoerceRmap :: (b -> b') -> p a b -> p a' b'
  icoerceRmap f = first absurd . dimap absurd f