- bimap :: (a -> b) -> (c -> d) -> p a c -> p b d
- first :: (a -> b) -> p a c -> p b c
- second :: (b -> c) -> p a b -> p a c

A run of the mill `Functor`

is covariant in a *single* type parameter. For instance, if `f`

is a `Functor`

, then given an `f a`

, and a function of the form `a -> b`

, one can obtain an `f b`

(through the use of `fmap`

).

A `Bifunctor`

is covariant in *two* type parameters. If `f`

is a `Bifunctor`

, then given an `f a b`

, and two functions, one from `a -> c`

, and another from `b -> d`

, then one can obtain an `f c d`

(using `bimap`

).

`first`

should be thought of as an `fmap`

over the first type parameter, `second`

as an `fmap`

over the second, and `bimap`

should be conceived as mapping two functions covariantly over the first and second type parameters, respectively.