Zulip Chat Archive
Stream: new members
Topic: Category types question
Julia Scheaffer (Oct 11 2025 at 16:53):
I have been trying to learn some category theory recently and I am trying to apply what I am learning in lean. Unfortunately, I am getting caught up on some type system issues with categories in lean. I defined a category I would like to work with, but I am having difficulties actually using these categories (I think) because they have the same types of objects but different types of morphisms.
import Mathlib.Tactic
import Mathlib.Logic.Function.Basic
import Mathlib.CategoryTheory.Category.Basic
import Mathlib.CategoryTheory.Functor.Basic
universe u
variable {α : Type u}
def IteratesTo (f : α -> α) (a b : α) :=
{ i : Nat // f^[i] a = b }
def IteratesTo.cat (F : α -> α) : CategoryTheory.Category α where
Hom := IteratesTo F
id x := ⟨0, Function.iterate_zero_apply F x⟩
comp f g := ⟨g.val + f.val, by
rw [Function.iterate_add_apply, f.property, g.property]⟩
id_comp _ := by ring_nf; rfl
comp_id _ := by ring_nf; rfl
assoc _ _ _ := by ring_nf
def f (n : Nat) : Nat := 2 * n
instance f.iterationCat : CategoryTheory.Category Nat := IteratesTo.cat f
def g (n : Nat) : Nat := 4 * n
instance g.iterationCat : CategoryTheory.Category Nat := IteratesTo.cat g
-- How do I create a functor between g.iterationCat and f.iterationCat?
-- It should map each object to the same value, and map each morphism to double it's previous value
-- My first attempt:
-- I need to specify the categories here, and they are inferred by default
example : CategoryTheory.Functor Nat Nat where
obj := id
map {X Y : Nat} (i : IteratesTo g X Y) : IteratesTo f (id X) (id Y) := sorry
This is my first attempt at trying to do category theory in lean with mathlib, so please let me know if I am defining my categories or functors incorrectly.
Joël Riou (Oct 11 2025 at 17:01):
Syntactically, when Lean sees α, it cannot know which category structure to use because it depends on F : α -> α. The standard procedure would be define a type synonym by def IteratesToCat (F : α -> α) := α and then define the category structure by instance : Category (IteratesToCat F) where .... Then, you may define a functor from IteratesToCat (fun (n : Nat) => 4 * n) to IteratesToCat (fun (n : Nat) => 2 * n).
Julia Scheaffer (Oct 11 2025 at 17:22):
That worked great, Thank you!
Here's the fully fixed code:
import Mathlib.Tactic
import Mathlib.Logic.Function.Basic
import Mathlib.CategoryTheory.Category.Basic
import Mathlib.CategoryTheory.Functor.Basic
universe u
variable {α : Type u}
def IteratesTo (f : α -> α) (a b : α) :=
{ i : Nat // f^[i] a = b }
def IteratesToCat (_ : α -> α) := α
instance IteratesTo.cat (F : α -> α) : CategoryTheory.Category (IteratesToCat F) where
Hom := IteratesTo F
id x := ⟨0, Function.iterate_zero_apply F x⟩
comp f g := ⟨g.val + f.val, by
rw [Function.iterate_add_apply, f.property, g.property]⟩
id_comp _ := by ring_nf; rfl
comp_id _ := by ring_nf; rfl
assoc _ _ _ := by ring_nf
def f (n : Nat) : Nat := 2 * n
def g (n : Nat) : Nat := 4 * n
theorem double_f_eq_g : f^[2] = g := by
funext x
change f (f x) = g x
dsimp only [f, g]
ring_nf
example : CategoryTheory.Functor (IteratesToCat g) (IteratesToCat f) where
obj := id
map {X Y : Nat} (i : IteratesTo g X Y) : IteratesTo f X Y :=
⟨2 * i.val, by rw [Function.iterate_mul, double_f_eq_g, i.property]⟩
map_comp _ _ := by
dsimp [CategoryTheory.CategoryStruct.comp]
ring_nf
Aaron Liu (Oct 11 2025 at 17:23):
probably the category it inferred is the preorder category, where there is a unique arrow a --> b iff a <= b
Last updated: Dec 20 2025 at 21:32 UTC