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
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
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.
(,) is an example of a type that has a
instance Bifunctor (,) where bimap f g (x, y) = (f x, g y)
bimap takes a pair of functions and applies them to the tuple's respective components.
bimap (+ 2) (++ "nie") (3, "john") --> (5,"johnnie") bimap ceiling length (3.5 :: Double, "john" :: String) --> (4,4)
Either's instance of
Bifunctor selects one of the two functions to apply depending on whether the value is
instance Bifunctor Either where bimap f g (Left x) = Left (f x) bimap f g (Right y) = Right (g y)
If mapping covariantly over only the first argument, or only the second argument, is desired, then
second ought to be used (in lieu of
first :: Bifunctor f => (a -> c) -> f a b -> f c b first f = bimap f id second :: Bifunctor f => (b -> d) -> f a b -> f a d second g = bimap id g
ghci> second (+ 2) (Right 40) Right 42 ghci> second (+ 2) (Left "uh oh") Left "uh oh"
Bifunctor is the class of types with two type parameters (
f :: * -> * -> *), both of which can be covariantly mapped over simultaneously.
class Bifunctor f where bimap :: (a -> c) -> (b -> d) -> f a b -> f c d
bimap can be thought of as applying a pair of
fmap operations to a datatype.
A correct instance of
Bifunctor for a type
f must satisfy the bifunctor laws, which are analogous to the functor laws:
bimap id id = id -- identity bimap (f . g) (h . i) = bimap f h . bimap g i -- composition
Bifunctor class is found in the
Data.Bifunctor module. For GHC versions >7.10, this module is bundled with the compiler; for earlier versions you need to install the