# Documentation

Mathlib.Control.Bifunctor

# Functors with two arguments #

This file defines bifunctors.

A bifunctor is a function F : Type* → Type* → Type* along with a bimap which turns F α βinto F α' β' given two functions α → α' and β → β'. It further

• respects the identity: bimap id id = id
• composes in the obvious way: (bimap f' g') ∘ (bimap f g) = bimap (f' ∘ f) (g' ∘ g)

## Main declarations #

• Bifunctor: A typeclass for the bare bimap of a bifunctor.
• LawfulBifunctor: A typeclass asserting this bimap respects the bifunctor laws.
class Bifunctor (F : Type u₀ → Type u₁ → Type u₂) :
Type (max (max (u₀ + 1) (u₁ + 1)) u₂)
• bimap : {α α' : Type u₀} → {β β' : Type u₁} → (αα') → (ββ') → F α βF α' β'

Lawless bifunctor. This typeclass only holds the data for the bimap.

Instances
class LawfulBifunctor (F : Type u₀ → Type u₁ → Type u₂) [] :
• id_bimap : ∀ {α : Type u₀} {β : Type u₁} (x : F α β), bimap id id x = x
• bimap_bimap : ∀ {α₀ α₁ α₂ : Type u₀} {β₀ β₁ β₂ : Type u₁} (f : α₀α₁) (f' : α₁α₂) (g : β₀β₁) (g' : β₁β₂) (x : F α₀ β₀), bimap f' g' (bimap f g x) = bimap (f' f) (g' g) x

Bifunctor. This typeclass asserts that a lawless Bifunctor is lawful.

Instances
theorem LawfulBifunctor.bimap_id_id {F : Type u₀ → Type u₁ → Type u₂} [] [self : ] {α : Type u₀} {β : Type u₁} :
bimap id id = id
theorem LawfulBifunctor.bimap_comp_bimap {F : Type u₀ → Type u₁ → Type u₂} [] [self : ] {α₀ : Type u₀} {α₁ : Type u₀} {α₂ : Type u₀} {β₀ : Type u₁} {β₁ : Type u₁} {β₂ : Type u₁} (f : α₀α₁) (f' : α₁α₂) (g : β₀β₁) (g' : β₁β₂) :
bimap f' g' bimap f g = bimap (f' f) (g' g)
@[reducible]
def Bifunctor.fst {F : Type u₀ → Type u₁ → Type u₂} [] {α : Type u₀} {α' : Type u₀} {β : Type u₁} (f : αα') :
F α βF α' β

Left map of a bifunctor.

Instances For
@[reducible]
def Bifunctor.snd {F : Type u₀ → Type u₁ → Type u₂} [] {α : Type u₀} {β : Type u₁} {β' : Type u₁} (f : ββ') :
F α βF α β'

Right map of a bifunctor.

Instances For
theorem Bifunctor.fst_id {F : Type u₀ → Type u₁ → Type u₂} [] [] {α : Type u₀} {β : Type u₁} :
= id
theorem Bifunctor.id_fst {F : Type u₀ → Type u₁ → Type u₂} [] [] {α : Type u₀} {β : Type u₁} (x : F α β) :
= x
theorem Bifunctor.snd_id {F : Type u₀ → Type u₁ → Type u₂} [] [] {α : Type u₀} {β : Type u₁} :
= id
theorem Bifunctor.id_snd {F : Type u₀ → Type u₁ → Type u₂} [] [] {α : Type u₀} {β : Type u₁} (x : F α β) :
= x
theorem Bifunctor.fst_comp_fst {F : Type u₀ → Type u₁ → Type u₂} [] [] {α₀ : Type u₀} {α₁ : Type u₀} {α₂ : Type u₀} {β : Type u₁} (f : α₀α₁) (f' : α₁α₂) :
theorem Bifunctor.comp_fst {F : Type u₀ → Type u₁ → Type u₂} [] [] {α₀ : Type u₀} {α₁ : Type u₀} {α₂ : Type u₀} {β : Type u₁} (f : α₀α₁) (f' : α₁α₂) (x : F α₀ β) :
theorem Bifunctor.fst_comp_snd {F : Type u₀ → Type u₁ → Type u₂} [] [] {α₀ : Type u₀} {α₁ : Type u₀} {β₀ : Type u₁} {β₁ : Type u₁} (f : α₀α₁) (f' : β₀β₁) :
= bimap f f'
theorem Bifunctor.fst_snd {F : Type u₀ → Type u₁ → Type u₂} [] [] {α₀ : Type u₀} {α₁ : Type u₀} {β₀ : Type u₁} {β₁ : Type u₁} (f : α₀α₁) (f' : β₀β₁) (x : F α₀ β₀) :
Bifunctor.fst f () = bimap f f' x
theorem Bifunctor.snd_comp_fst {F : Type u₀ → Type u₁ → Type u₂} [] [] {α₀ : Type u₀} {α₁ : Type u₀} {β₀ : Type u₁} {β₁ : Type u₁} (f : α₀α₁) (f' : β₀β₁) :
= bimap f f'
theorem Bifunctor.snd_fst {F : Type u₀ → Type u₁ → Type u₂} [] [] {α₀ : Type u₀} {α₁ : Type u₀} {β₀ : Type u₁} {β₁ : Type u₁} (f : α₀α₁) (f' : β₀β₁) (x : F α₀ β₀) :
Bifunctor.snd f' () = bimap f f' x
theorem Bifunctor.snd_comp_snd {F : Type u₀ → Type u₁ → Type u₂} [] [] {α : Type u₀} {β₀ : Type u₁} {β₁ : Type u₁} {β₂ : Type u₁} (g : β₀β₁) (g' : β₁β₂) :
theorem Bifunctor.comp_snd {F : Type u₀ → Type u₁ → Type u₂} [] [] {α : Type u₀} {β₀ : Type u₁} {β₁ : Type u₁} {β₂ : Type u₁} (g : β₀β₁) (g' : β₁β₂) (x : F α β₀) :
instance Bifunctor.flip {F : Type u₀ → Type u₁ → Type u₂} [] :
instance LawfulBifunctor.flip {F : Type u₀ → Type u₁ → Type u₂} [] [] :
instance Bifunctor.functor {F : Type u₀ → Type u₁ → Type u₂} [] {α : Type u₀} :
Functor (F α)
instance Bifunctor.lawfulFunctor {F : Type u₀ → Type u₁ → Type u₂} [] [] {α : Type u₀} :
instance Function.bicompl.bifunctor {F : Type u₀ → Type u₁ → Type u₂} [] (G : Type u_1 → Type u₀) (H : Type u_2 → Type u₁) [] [] :
instance Function.bicompl.lawfulBifunctor {F : Type u₀ → Type u₁ → Type u₂} [] (G : Type u_1 → Type u₀) (H : Type u_2 → Type u₁) [] [] [] [] [] :
instance Function.bicompr.bifunctor {F : Type u₀ → Type u₁ → Type u₂} [] (G : Type u₂ → Type u_1) [] :
instance Function.bicompr.lawfulBifunctor {F : Type u₀ → Type u₁ → Type u₂} [] (G : Type u₂ → Type u_1) [] [] [] :