Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
Try doing some basic maths questions in the Lean Theorem Prover. Functions, real numbers, equivalence relations and groups. Click on README.md and then on "Open in CoCalc with one click".
Project: Xena
Views: 18536License: APACHE
/- Copyright (c) 2018 Simon Hudon. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Author: Simon Hudon Functors with two arguments -/ import logic.function data.sum category.basic category.functor tactic.basic universes u₀ u₁ u₂ v₀ v₁ v₂ open function class bifunctor (F : Type u₀ → Type u₁ → Type u₂) := (bimap : Π {α α' β β'}, (α → α') → (β → β') → F α β → F α' β') export bifunctor ( bimap ) class is_lawful_bifunctor (F : Type u₀ → Type u₁ → Type u₂) [bifunctor F] := (id_bimap : Π {α β} (x : F α β), bimap id id x = x) (bimap_bimap : Π {α₀ α₁ α₂ β₀ β₁ β₂} (f : α₀ → α₁) (f' : α₁ → α₂) (g : β₀ → β₁) (g' : β₁ → β₂) (x : F α₀ β₀), bimap f' g' (bimap f g x) = bimap (f' ∘ f) (g' ∘ g) x) export is_lawful_bifunctor (id_bimap bimap_bimap) attribute [higher_order bimap_id_id] id_bimap attribute [higher_order bimap_comp_bimap] bimap_bimap export is_lawful_bifunctor (bimap_id_id bimap_comp_bimap) variables {F : Type u₀ → Type u₁ → Type u₂} [bifunctor F] namespace bifunctor @[reducible] def fst {α α' β} (f : α → α') : F α β → F α' β := bimap f id @[reducible] def snd {α β β'} (f : β → β') : F α β → F α β' := bimap id f variable [is_lawful_bifunctor F] @[higher_order fst_id] lemma id_fst : Π {α β} (x : F α β), fst id x = x := @id_bimap _ _ _ @[higher_order snd_id] lemma id_snd : Π {α β} (x : F α β), snd id x = x := @id_bimap _ _ _ @[higher_order fst_comp_fst] lemma comp_fst {α₀ α₁ α₂ β} (f : α₀ → α₁) (f' : α₁ → α₂) (x : F α₀ β) : fst f' (fst f x) = fst (f' ∘ f) x := by simp [fst,bimap_bimap] @[higher_order fst_comp_snd] lemma fst_snd {α₀ α₁ β₀ β₁} (f : α₀ → α₁) (f' : β₀ → β₁) (x : F α₀ β₀) : fst f (snd f' x) = bimap f f' x := by simp [fst,bimap_bimap] @[higher_order snd_comp_fst] lemma snd_fst {α₀ α₁ β₀ β₁} (f : α₀ → α₁) (f' : β₀ → β₁) (x : F α₀ β₀) : snd f' (fst f x) = bimap f f' x := by simp [snd,bimap_bimap] @[higher_order snd_comp_snd] lemma comp_snd {α β₀ β₁ β₂} (g : β₀ → β₁) (g' : β₁ → β₂) (x : F α β₀) : snd g' (snd g x) = snd (g' ∘ g) x := by simp [snd,bimap_bimap] attribute [functor_norm] bimap_bimap comp_snd comp_fst snd_comp_snd snd_comp_fst fst_comp_snd fst_comp_fst bimap_comp_bimap bimap_id_id fst_id snd_id end bifunctor open functor instance : bifunctor prod := { bimap := @prod.map } instance : is_lawful_bifunctor prod := by refine { .. }; intros; cases x; refl instance bifunctor.const : bifunctor const := { bimap := (λ α α' β β f _, f) } instance is_lawful_bifunctor.const : is_lawful_bifunctor const := by refine { .. }; intros; refl instance bifunctor.flip : bifunctor (flip F) := { bimap := (λ α α' β β' f f' x, (bimap f' f x : F β' α')) } instance is_lawful_bifunctor.flip [is_lawful_bifunctor F] : is_lawful_bifunctor (flip F) := by refine { .. }; intros; simp [bimap] with functor_norm instance : bifunctor sum := { bimap := @sum.map } instance : is_lawful_bifunctor sum := by refine { .. }; intros; cases x; refl open bifunctor functor @[priority 10] instance bifunctor.functor {α} : functor (F α) := { map := λ _ _, snd } @[priority 10] instance bifunctor.is_lawful_functor [is_lawful_bifunctor F] {α} : is_lawful_functor (F α) := by refine {..}; intros; simp [functor.map] with functor_norm section bicompl variables (G : Type* → Type u₀) (H : Type* → Type u₁) [functor G] [functor H] instance : bifunctor (bicompl F G H) := { bimap := λ α α' β β' f f' x, (bimap (map f) (map f') x : F (G α') (H β')) } instance [is_lawful_functor G] [is_lawful_functor H] [is_lawful_bifunctor F] : is_lawful_bifunctor (bicompl F G H) := by constructor; intros; simp [bimap,map_id,map_comp_map] with functor_norm end bicompl section bicompr variables (G : Type u₂ → Type*) [functor G] instance : bifunctor (bicompr G F) := { bimap := λ α α' β β' f f' x, (map (bimap f f') x : G (F α' β')) } instance [is_lawful_functor G] [is_lawful_bifunctor F] : is_lawful_bifunctor (bicompr G F) := by constructor; intros; simp [bimap] with functor_norm end bicompr