HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Modulebase-compat-0.14.1Haskell2010

Data.Bifunctor.Compat

  • 1 class
classclass (forall a. Functor (p a)) => Bifunctor (p :: Type -> Type -> Type) where
#

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.

The class definition of a Bifunctor p uses the QuantifiedConstraints language extension to quantify over the first type argument a in its context. The context requires that p a must be a Functor for all a. In other words a partially applied Bifunctor must be a Functor. This makes Functor a superclass of Bifunctor such that a function with a Bifunctor constraint may use fmap in its implementation. Functor has been a quantified superclass of Bifunctor since base-4.18.0.0.

You can define a Bifunctor by either defining bimap or by defining both first and second. The second method must agree with fmap:

second ≡ fmap

From this it follows that:

second id ≡ id

If you supply bimap, you should ensure that:

bimap id id ≡ id

If you supply first and second, ensure:

first id ≡ id
second id ≡ id

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

Methods

  • bimap :: (a -> b) -> (c -> d) -> p a c -> p b d

    Map over both arguments at the same time.

    bimap f g ≡ first f . second g
    Examples
    Example1 expression
    bimap toUpper (+1) ('j', 3)('J',4)
    Example1 expression
    bimap toUpper (+1) (Left 'j')Left 'J'
    Example1 expression
    bimap toUpper (+1) (Right 3)Right 4
  • first :: (a -> b) -> p a c -> p b c

    Map covariantly over the first argument.

    first f ≡ bimap f id
    Examples
    Example1 expression
    first toUpper ('j', 3)('J',3)
    Example1 expression
    first toUpper (Left 'j')Left 'J'
  • second :: (b -> c) -> p a b -> p a c

    Map covariantly over the second argument.

    second ≡ bimap id
    Examples
    Example1 expression
    second (+1) ('j', 3)('j',4)
    Example1 expression
    second (+1) (Right 3)Right 4
Instances11Bifunctor, …
  • Bifunctor ArgDefined in base-4.20.2.0 · Data.Semigroup
  • Bifunctor EitherDefined in base-4.20.2.0 · Data.Bifunctor
  • Bifunctor Tuple2Defined in base-4.20.2.0 · Data.Bifunctor

    Class laws for tuples hold only up to laziness. Both first id and second id are lazier than id (and fmap id):

    Example3 expressions
    first id (undefined :: (Int, Word)) `seq` ()()second id (undefined :: (Int, Word)) `seq` ()()id (undefined :: (Int, Word)) `seq` ()*** Exception: Prelude.undefined
  • Bifunctor ConstDefined in base-4.20.2.0 · Data.Bifunctor
  • Bifunctor ConstantDefined in transformers-0.6.1.1 · Data.Functor.Constant
  • Bifunctor (Tuple3 x1)Defined in base-4.20.2.0 · Data.Bifunctor
  • Bifunctor (K1 i)Defined in base-4.20.2.0 · Data.Bifunctor
  • Bifunctor (Tuple4 x1 x2)Defined in base-4.20.2.0 · Data.Bifunctor
  • Bifunctor (Tuple5 x1 x2 x3)Defined in base-4.20.2.0 · Data.Bifunctor
  • Bifunctor (Tuple6 x1 x2 x3 x4)Defined in base-4.20.2.0 · Data.Bifunctor
  • Bifunctor (Tuple7 x1 x2 x3 x4 x5)Defined in base-4.20.2.0 · Data.Bifunctor