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.
theorem
Bifunctor.fst_id
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
{α : Type u₀}
{β : Type u₁}
:
Bifunctor.fst id = id
theorem
Bifunctor.id_fst
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
{α : Type u₀}
{β : Type u₁}
(x : F α β)
:
Bifunctor.fst id x = x
theorem
Bifunctor.snd_id
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
{α : Type u₀}
{β : Type u₁}
:
Bifunctor.snd id = id
theorem
Bifunctor.id_snd
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
{α : Type u₀}
{β : Type u₁}
(x : F α β)
:
Bifunctor.snd id x = x
theorem
Bifunctor.fst_comp_fst
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
{α₀ : Type u₀}
{α₁ : Type u₀}
{α₂ : Type u₀}
{β : Type u₁}
(f : α₀ → α₁)
(f' : α₁ → α₂)
:
Bifunctor.fst f' ∘ Bifunctor.fst f = Bifunctor.fst (f' ∘ f)
theorem
Bifunctor.comp_fst
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
{α₀ : Type u₀}
{α₁ : Type u₀}
{α₂ : Type u₀}
{β : Type u₁}
(f : α₀ → α₁)
(f' : α₁ → α₂)
(x : F α₀ β)
:
Bifunctor.fst f' (Bifunctor.fst f x) = Bifunctor.fst (f' ∘ f) x
theorem
Bifunctor.fst_comp_snd
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
{α₀ : Type u₀}
{α₁ : Type u₀}
{β₀ : Type u₁}
{β₁ : Type u₁}
(f : α₀ → α₁)
(f' : β₀ → β₁)
:
Bifunctor.fst f ∘ Bifunctor.snd f' = bimap f f'
theorem
Bifunctor.fst_snd
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
{α₀ : Type u₀}
{α₁ : Type u₀}
{β₀ : Type u₁}
{β₁ : Type u₁}
(f : α₀ → α₁)
(f' : β₀ → β₁)
(x : F α₀ β₀)
:
Bifunctor.fst f (Bifunctor.snd f' x) = bimap f f' x
theorem
Bifunctor.snd_comp_fst
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
{α₀ : Type u₀}
{α₁ : Type u₀}
{β₀ : Type u₁}
{β₁ : Type u₁}
(f : α₀ → α₁)
(f' : β₀ → β₁)
:
Bifunctor.snd f' ∘ Bifunctor.fst f = bimap f f'
theorem
Bifunctor.snd_fst
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
{α₀ : Type u₀}
{α₁ : Type u₀}
{β₀ : Type u₁}
{β₁ : Type u₁}
(f : α₀ → α₁)
(f' : β₀ → β₁)
(x : F α₀ β₀)
:
Bifunctor.snd f' (Bifunctor.fst f x) = bimap f f' x
theorem
Bifunctor.snd_comp_snd
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
{α : Type u₀}
{β₀ : Type u₁}
{β₁ : Type u₁}
{β₂ : Type u₁}
(g : β₀ → β₁)
(g' : β₁ → β₂)
:
Bifunctor.snd g' ∘ Bifunctor.snd g = Bifunctor.snd (g' ∘ g)
theorem
Bifunctor.comp_snd
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
{α : Type u₀}
{β₀ : Type u₁}
{β₁ : Type u₁}
{β₂ : Type u₁}
(g : β₀ → β₁)
(g' : β₁ → β₂)
(x : F α β₀)
:
Bifunctor.snd g' (Bifunctor.snd g x) = Bifunctor.snd (g' ∘ g) x
Equations
- Bifunctor.const = { bimap := fun {α α'} {β β'} f x => f }
instance
LawfulBifunctor.flip
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
:
LawfulBifunctor (flip F)
instance
Bifunctor.functor
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
{α : Type u₀}
:
Functor (F α)
Equations
- Bifunctor.functor = { map := fun {α β} f x => Bifunctor.snd f x, mapConst := fun {α β} => (fun f x => Bifunctor.snd f x) ∘ Function.const β }
instance
Bifunctor.lawfulFunctor
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
[LawfulBifunctor F]
{α : Type u₀}
:
LawfulFunctor (F α)
instance
Function.bicompl.bifunctor
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
(G : Type u_1 → Type u₀)
(H : Type u_2 → Type u₁)
[Functor G]
[Functor H]
:
Bifunctor (Function.bicompl F G H)
Equations
- Function.bicompl.bifunctor G H = { bimap := fun {_α α'} {_β β'} f f' x => bimap (Functor.map f) (Functor.map f') x }
instance
Function.bicompl.lawfulBifunctor
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
(G : Type u_1 → Type u₀)
(H : Type u_2 → Type u₁)
[Functor G]
[Functor H]
[LawfulFunctor G]
[LawfulFunctor H]
[LawfulBifunctor F]
:
LawfulBifunctor (Function.bicompl F G H)
instance
Function.bicompr.bifunctor
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
(G : Type u₂ → Type u_1)
[Functor G]
:
Bifunctor (Function.bicompr G F)
Equations
- Function.bicompr.bifunctor G = { bimap := fun {_α α'} {_β β'} f f' x => bimap f f' <$> x }
instance
Function.bicompr.lawfulBifunctor
{F : Type u₀ → Type u₁ → Type u₂}
[Bifunctor F]
(G : Type u₂ → Type u_1)
[Functor G]
[LawfulFunctor G]
[LawfulBifunctor F]
: