A bifunctor is a type constructor $F : \mathsf{Type} \to \mathsf{Type} \to \mathsf{Type}$ that is functorial in both arguments. Given morphisms $f : \alpha \to \gamma$ and $g : \beta \to \delta$, we obtain:
$$\text{bimap}\; f\; g : F\;\alpha\;\beta \to F\;\gamma\;\delta$$
Map over both arguments simultaneously: $\text{bimap}\; f\; g : F\;\alpha\;\beta \to F\;\gamma\;\delta$.
Map over the first argument only: $\text{mapFst}\; f = \text{bimap}\; f\; \text{id}$.
Map over the second argument only: $\text{mapSnd}\; g = \text{bimap}\; \text{id}\; g$.
Instances
Laws that a well-behaved Bifunctor must satisfy:
- Identity: $\text{bimap}\;\text{id}\;\text{id} = \text{id}$
- Composition: $\text{bimap}\;(f_1 \circ f_2)\;(g_1 \circ g_2) = \text{bimap}\;f_1\;g_1 \circ \text{bimap}\;f_2\;g_2$
Identity law: $\text{bimap}\;\text{id}\;\text{id}\;x = x$.
- bimap_comp {γ δ α : Type u} {ε ζ β : Type v} (f₁ : γ → δ) (f₂ : α → γ) (g₁ : ε → ζ) (g₂ : β → ε) (x : F α β) : Bifunctor.bimap (f₁ ∘ f₂) (g₁ ∘ g₂) x = Bifunctor.bimap f₁ g₁ (Bifunctor.bimap f₂ g₂ x)
Composition law: $\text{bimap}\;(f_1 \circ f_2)\;(g_1 \circ g_2)\;x = \text{bimap}\;f_1\;g_1\;(\text{bimap}\;f_2\;g_2\;x)$.
Instances
Prod is a lawful bifunctor — both laws hold definitionally.
Sum is a lawful bifunctor — proved by case analysis.
Except is a lawful bifunctor — proved by case analysis.