Zulip Chat Archive
Stream: mathlib4
Topic: Definition of (category theory) monad
Gareth Ma (Aug 06 2025 at 23:28):
The assoc field of Monad is defined as
assoc : ∀ X, toFunctor.map (NatTrans.app μ X) ≫ μ.app _ = μ.app _ ≫ μ.app _ := by aesop_cat
Why is this definition used instead of the more natural / correct
whiskerLeft _ μ ≫ μ = whiskerRight μ _ ≫ μ
Kenny Lau (Aug 06 2025 at 23:29):
(you need \ggg right?)
Gareth Ma (Aug 06 2025 at 23:30):
No because \mu is a natural transformation
Aaron Liu (Aug 06 2025 at 23:30):
You are abusing the defeq that functor composition is associative
Gareth Ma (Aug 06 2025 at 23:30):
Yes
Gareth Ma (Aug 06 2025 at 23:30):
But they're defeq and Mathlib/CategoryTheory does that all the time anyways?
Gareth Ma (Aug 06 2025 at 23:31):
Or is it maybe because it was ported from Lean 3 and back then it wasn't defeq (I have no idea)
Gareth Ma (Aug 06 2025 at 23:31):
Okay a better question, is it a good idea to change this?
Aaron Liu (Aug 06 2025 at 23:31):
no the reason is that abusing defeq is bad
Aaron Liu (Aug 06 2025 at 23:32):
even though it's already done in a lot of places
Gareth Ma (Aug 06 2025 at 23:50):
How is it bad? Plus it's not even abusing defeq, and if you don't like it / want to recover the current definition just ext or ext1 or something
Aaron Liu (Aug 07 2025 at 00:08):
Gareth Ma said:
Plus it's not even abusing defeq
what?
Robin Arnez (Aug 07 2025 at 10:05):
I would consider the definition of defeq abuse to be "doesn't typecheck at reducible transparency":
import Mathlib
open CategoryTheory
variable {C : Type*} [Category.{v} C]
open private Lean.Meta.checkAux from Lean.Meta.Check
open Functor in
def test (x : Monad C) : whiskerLeft _ x.μ ≫ x.μ = whiskerRight x.μ _ ≫ x.μ := by
sorry
open Lean Meta
/--
error: Application type mismatch: In the application
x.whiskerLeft x.μ ≫ x.μ = Functor.whiskerRight x.μ x.toFunctor ≫ x.μ
the argument
Functor.whiskerRight x.μ x.toFunctor ≫ x.μ
has type
(x.toFunctor ⋙ x.toFunctor) ⋙ x.toFunctor ⟶ x.toFunctor : Type (max u_1 v)
but is expected to have type
x.toFunctor ⋙ x.toFunctor ⋙ x.toFunctor ⟶ x.toFunctor : Type (max v u_1)
-/
#guard_msgs in
run_meta
let val ← getConstVal ``test
let type := val.type
withReducible <| Lean.Meta.checkAux type
The problem here is that many tactics like simp operate on reducible transparency, so they might run into problems when trying to operate.
Adam Topaz (Aug 07 2025 at 16:29):
@Gareth Ma you could take a look at how we define docs#Mon_class (and also how Comon_class is used to define comonads in a bicategory in mathlib)
Adam Topaz (Aug 07 2025 at 16:29):
Note in particular the explicit use of associators and unitors
Gareth Ma (Aug 07 2025 at 16:30):
For monoidal categories it makes sense since that’s data
Gareth Ma (Aug 07 2025 at 16:30):
But here it’s defeq right
Gareth Ma (Aug 07 2025 at 16:31):
(I hope I’m understanding your point correctly, I’m on phone right now but I can double check later)
Gareth Ma (Aug 07 2025 at 16:33):
Or another question, is it a good idea to change the Monad assoc definition from the current one to what I suggested (with whiskering) but with associators added in
Gareth Ma (Aug 07 2025 at 16:33):
Functor.assoc or something iirc
Aaron Liu (Aug 07 2025 at 16:33):
I don't think we have the associators and unitor natural transformations for functor composition
Aaron Liu (Aug 07 2025 at 16:34):
I guess it's just eqToHom
Joël Riou (Aug 07 2025 at 16:35):
We used to abuse defeq for associators/unitors, but it turns out it is better practice to insert associators in definitions. Here it would be ok to make a lemma for this compatibility at the level of natural transformations, adding a different constructor, or even changing the definition.
Gareth Ma (Aug 07 2025 at 16:35):
No it's CategoryTheory.Functor.associator
Aaron Liu (Aug 07 2025 at 16:35):
Gareth Ma said:
Oh I must have missed it
Gareth Ma (Aug 07 2025 at 16:36):
Joël Riou said:
We used to abuse defeq for associators/unitors, but it turns out it is better practice to insert associators in definitions. Here it would be ok to make a lemma for this compatibility at the level of natural transformations, adding a different constructor, or even changing the definition.
So changing Monad.assoc definition to whiskerLeft _ μ \ggg Functor.associator something ≫ μ = whiskerRight μ _ ≫ Functor.associator something \ggg μ would fit what you're saying right
Gareth Ma (Aug 07 2025 at 16:37):
(Whatever the correct statement is)
Adam Topaz (Aug 07 2025 at 16:39):
Sure, I think such a defitinion could be made. But does this give any advantage?
Adam Topaz (Aug 07 2025 at 16:40):
Monads and comonads are inherently a 2-categorical thing, and IMO the right abstraction is at that level.
Gareth Ma (Aug 07 2025 at 16:40):
It’s what’s found in textbooks, you can recover the existing one with ext, but going the other way around seems more annoying (I used fun x -> congrArg (fun a -> a.app X or something)
Adam Topaz (Aug 07 2025 at 16:42):
I think if you want to work at the level of natural transformations without applying them to a particular object, then you should formulate things in terms of bicategories
Adam Topaz (Aug 07 2025 at 16:43):
cf docs#CategoryTheory.Bicategory.Comonad
Gareth Ma (Aug 07 2025 at 16:44):
Okay I will try that out then. I know it’s the natural place to do monad stuff but I just didn’t want to touch/learn it :) Thanks for the comments
Gareth Ma (Aug 07 2025 at 16:46):
So eg the statement “if a category has all limits then the codensity monad of a functor exists” should be in Bicategory?
Robin Arnez (Aug 07 2025 at 16:46):
For an example of defeq abuse, here:
import Mathlib
theorem List.findFinIdx?_cons_eq_some_succ_iff (p : α → Bool) (x : α) (l : List α) (i : Fin l.length) :
(x :: l).findFinIdx? p = some i.succ ↔ p x = false ∧ l.findFinIdx? p = some i := by
rw [findFinIdx?_cons]
split
· simp_all [(Fin.succ_ne_zero _).symm]
· simp_all only [Option.map_eq_some_iff, Fin.succ_inj, exists_eq_right, Bool.not_eq_true, true_and]
-- basically the same statement
example (p : α → Bool) (x : α) (l : List α) (i : Fin l.length) :
some i.succ = (x :: l).findFinIdx? p ↔ p x = false ∧ l.findFinIdx? p = some i := by
rw [eq_comm]
simp only [List.findFinIdx?_cons_eq_some_succ_iff] -- fails!!!
Adam Topaz (Aug 07 2025 at 16:47):
Gareth Ma said:
So eg the statement “if a category has all limits then the codensity monad of a functor exists” should be in Bicategory?
I think this is a statement about Kan extensions
Gareth Ma (Aug 07 2025 at 16:47):
Yes
Robin Arnez (Aug 07 2025 at 16:47):
In this example, the defeq abuse of (x :: l).length = l.length + 1 causes problems because the Eq in the statement is about Fin (x :: l).length and we use it on Fin (l.length + 1) later
Gareth Ma (Aug 07 2025 at 16:48):
Codensity monad = Right Kan extension of F along F exists
Aaron Liu (Aug 07 2025 at 16:59):
import Mathlib
universe u v
open CategoryTheory
def CategoryTheory.Monad.mk' {C : Type u} [Category.{v} C] (T : C ⥤ C) (η : 𝟭 C ⟶ T) (μ : T ⋙ T ⟶ T)
(mul_assoc : CategoryTheory.Functor.whiskerRight μ T ≫ μ =
(T.associator T T).hom ≫ CategoryTheory.Functor.whiskerLeft T μ ≫ μ)
(one_mul : CategoryTheory.Functor.whiskerLeft T η ≫ μ = T.rightUnitor.hom)
(mul_one : CategoryTheory.Functor.whiskerRight η T ≫ μ = T.leftUnitor.hom) : Monad C :=
{ T with
μ, η
assoc X := by simpa using congr(($mul_assoc).app X)
left_unit X := congr(($one_mul).app X)
right_unit X := congr(($mul_one).app X) }
Gareth Ma (Aug 07 2025 at 17:00):
Where can I learn more about the $ notation
Gareth Ma (Aug 07 2025 at 17:00):
Wth is that
Aaron Liu (Aug 07 2025 at 17:00):
it's a monad
Aaron Liu (Aug 07 2025 at 17:01):
see, there's the associativity, and there's the left and right unit equations
Ruben Van de Velde (Aug 07 2025 at 17:01):
The one in congr? That's part of the congr syntax itself
Aaron Liu (Aug 07 2025 at 17:06):
oh this works too
import Mathlib
universe u v
open CategoryTheory
def CategoryTheory.Monad.mk' {C : Type u} [Category.{v} C] (T : C ⥤ C) (η : 𝟭 C ⟶ T) (μ : T ⋙ T ⟶ T)
(mul_assoc : CategoryTheory.Functor.whiskerRight μ T ≫ μ =
(T.associator T T).hom ≫ CategoryTheory.Functor.whiskerLeft T μ ≫ μ)
(one_mul : CategoryTheory.Functor.whiskerLeft T η ≫ μ = T.rightUnitor.hom)
(mul_one : CategoryTheory.Functor.whiskerRight η T ≫ μ = T.leftUnitor.hom) : Monad C where
toFunctor := T
μ
η
assoc X := by simpa using congr(($mul_assoc).app X)
left_unit X := congr(($one_mul).app X)
right_unit X := congr(($mul_one).app X)
Aaron Liu (Aug 07 2025 at 17:06):
those lines with one character are so weird
Last updated: Dec 20 2025 at 21:32 UTC