Functor module:Data package:semigroupoids

A type f is a Functor if it provides a function fmap which, given any types a and b lets you apply any function from (a -> b) to turn an f a into an f b, preserving the structure of f. Furthermore f needs to adhere to the following: Note, that the second law follows from the free theorem of the type fmap and the first law, so you need only check that the former condition holds.
A bifunctor is a type constructor that takes two type arguments and is a functor in both arguments. That is, unlike with Functor, a type constructor such as Either does not need to be partially applied for a Bifunctor instance, and the methods in this class permit mapping functions over the Left value or the Right value, or both at the same time. Formally, the class Bifunctor represents a bifunctor from Hask -> Hask. Intuitively it is a bifunctor where both the first and second arguments are covariant. You can define a Bifunctor by either defining bimap or by defining both first and second. If you supply bimap, you should ensure that:
bimap id idid
If you supply first and second, ensure:
first idid
second idid
If you supply both, you should also ensure:
bimap f g ≡ first f . second g
These ensure by parametricity:
bimap  (f . g) (h . i) ≡ bimap f h . bimap g i
first  (f . g) ≡ first  f . first  g
second (f . g) ≡ second f . second g