Zulip Chat Archive
Stream: general
Topic: option.map_comp
Kevin Buzzard (Mar 23 2019 at 20:45):
What is option.map_comp called? I can't find it :-/ Oh! Is it something to do with monads?
Sebastian Ullrich (Mar 23 2019 at 20:59):
Yes, it's comp_map
(of class is_lawful_functor
)
Kevin Buzzard (Mar 23 2019 at 22:51):
Can I get this cheaply?
def with_zero (α) := option α instance : monad with_zero := option.monad namespace with_zero def map {α β : Type*} (f : α → β) : with_zero α → with_zero β := option.map f lemma map_id {α : Type*} : map (id : α → α) = id := option.map_id lemma map_comp {α : Type*} {β : Type*} {γ : Type*} (f : α → β) (g : β → γ) (r : with_zero α) : with_zero.map (g ∘ f) r = (with_zero.map g) ((with_zero.map f) r) := is_lawful_functor.comp_map f g r -- error involving <$> /- type mismatch, term comp_map ?m_7 ?m_8 ?m_9 has type (?m_6 ∘ ?m_7) <$> ?m_8 = ?m_6 <$> ?m_7 <$> ?m_8 but is expected to have type map (g ∘ f) r = map g (map f r) -/ end with_zero
I have never had to deal with <$>
before.
Chris Hughes (Mar 23 2019 at 22:57):
Have you proved it's a lawful monad?
Kevin Buzzard (Mar 23 2019 at 22:57):
def map {α β : Type*} (f : α → β) : with_zero α → with_zero β := functor.map f
This fixes it.
Kevin Buzzard (Mar 23 2019 at 22:58):
I've proved it's a functor:
example : functor with_zero := by apply_instance
Kevin Buzzard (Mar 23 2019 at 22:58):
Or at least, someone did...
Chris Hughes (Mar 23 2019 at 22:59):
Don't you need to prove it's a lawful functor?
Kevin Buzzard (Mar 23 2019 at 23:01):
def with_zero (α) := option α instance : monad with_zero := option.monad namespace with_zero def map {α β : Type*} (f : α → β) : with_zero α → with_zero β := functor.map f lemma map_id {α : Type*} : map (id : α → α) = id := option.map_id lemma map_comp {α : Type*} {β : Type*} {γ : Type*} (f : α → β) (g : β → γ) (r : with_zero α) : with_zero.map (g ∘ f) r = (with_zero.map g) ((with_zero.map f) r) := is_lawful_functor.comp_map f g r -- compiles fine example : is_lawful_functor with_zero := by apply_instance -- fails! end with_zero
Apparently not :P
Kevin Buzzard (Mar 23 2019 at 23:02):
I've never played with this stuff before.
Kevin Buzzard (Mar 23 2019 at 23:10):
example : is_lawful_functor option := by apply_instance -- works!
Kevin Buzzard (Mar 23 2019 at 23:11):
I am surprised things work out like this. Type class inference found an instance for is_lawful_functor with_zero
when using is_lawful_functor.comp_map
but not when I asked it explicitly.
Kevin Buzzard (Mar 23 2019 at 23:17):
Am I supposed to be writing code like this in a library:
def with_zero (α) := option α instance : monad with_zero := option.monad example : is_lawful_functor with_zero := show is_lawful_functor option, by apply_instance example : is_lawful_monad with_zero := show is_lawful_monad option, by apply_instance namespace with_zero def map {α β : Type*} (f : α → β) : with_zero α → with_zero β := functor.map f lemma map_id {α : Type*} : map (id : α → α) = id := option.map_id lemma map_comp {α : Type*} {β : Type*} {γ : Type*} (f : α → β) (g : β → γ) (r : with_zero α) : with_zero.map (g ∘ f) r = (with_zero.map g) ((with_zero.map f) r) := is_lawful_functor.comp_map f g r end with_zero
Or am I just supposed to use is_lawful_functor.comp_map
whenever I want with_zero.comp_map
?
Kevin Buzzard (Mar 23 2019 at 23:18):
It's the same question Johan asked earlier with vector_subspace.zero_mem just equalling submodule.zero_mem.
Patrick Massot (Mar 24 2019 at 08:13):
What about using open is_lawful_functor
and stop worrying?
Kevin Buzzard (Mar 24 2019 at 08:43):
Is that what I'm supposed to do?
Kevin Buzzard (Mar 24 2019 at 09:05):
aargh functor is rubbish
class functor (f : Type u → Type v) : Type (max (u+1) v) := (map : Π {α β : Type u}, (α → β) → f α → f β) (map_const : Π {α β : Type u}, α → f β → f α := λ α β, map ∘ const β)
functor.map
will only eat f : alpha -> beta
if alpha and beta live in the same universe :-(
Kevin Buzzard (Mar 24 2019 at 09:05):
I don't think this is general enough for me after all
Kevin Buzzard (Mar 24 2019 at 09:13):
So I'm back to the start.
universes u₁ u₂ u₃ def option.map_comp {α : Type u₁} {β : Type u₂} {γ : Type u₃} (f : α → β) (g : β → γ) (r : option α) : option.map (g ∘ f) r = option.map g (option.map f r) := sorry
Is this in Lean or mathlib somewhere?
Mario Carneiro (Mar 24 2019 at 09:24):
I don't think it is, it should be in data.option.basic
Kevin Buzzard (Mar 24 2019 at 09:25):
You can't prove it using lawful functors, or at least I can't, because then the universes have to be the same.
Mario Carneiro (Mar 24 2019 at 09:25):
This is a known limitation of functor
Mario Carneiro (Mar 24 2019 at 09:26):
this is why many monads have map
functions separate from the notation
Kevin Buzzard (Mar 24 2019 at 09:26):
You want this sort of thing to construct an equiv of monoids (with_zero G) from an equiv of groups (G)
Mario Carneiro (Mar 24 2019 at 09:26):
I guess it's just a semigroup equiv?
Kevin Buzzard (Mar 24 2019 at 09:27):
A semigroup equiv of monoids is a monoid equiv, if I've understood this statement correctly
Mario Carneiro (Mar 24 2019 at 09:27):
with_zero
makes a semigroup into a monoid
Kevin Buzzard (Mar 24 2019 at 09:28):
Aah I see. Yes.
Mario Carneiro (Mar 24 2019 at 09:28):
so the congr theorem should turn semigroup equivs into monoid equivs
Kevin Buzzard (Mar 24 2019 at 09:28):
Right.
Kevin Buzzard (Mar 24 2019 at 09:28):
Oh this is more congr?
Mario Carneiro (Mar 24 2019 at 09:28):
yeah, if you squint
Kevin Buzzard (Mar 24 2019 at 09:28):
I'm learning to squint at congr.
Mario Carneiro (Mar 24 2019 at 09:29):
G ~= H -> with_zero G ~= with_zero H
Kevin Buzzard (Mar 24 2019 at 09:29):
yes, that's a congr alright.
Kevin Buzzard (Mar 24 2019 at 09:29):
So what's the function called?
Mario Carneiro (Mar 24 2019 at 09:29):
with_zero_congr
?
Kevin Buzzard (Mar 24 2019 at 09:29):
I don't think I'll tell you what I was going to call it.
Mario Carneiro (Mar 24 2019 at 09:29):
or maybe something with projection notation
Kevin Buzzard (Mar 24 2019 at 09:30):
semigroup_equiv.with_zero_congr?
Mario Carneiro (Mar 24 2019 at 09:30):
semigroup_equiv.with_zero_congr
doesn't buy much
Kevin Buzzard (Mar 24 2019 at 15:29):
Ohohoh I just sat down to code this and noticed that it is from groups to monoids -- the group law is *
, so this extra zero isn't the monoid identity. Maybe it's from monoids to monoids.
Kevin Buzzard (Mar 24 2019 at 15:36):
def to_with_zero_monoid_equiv (h : monoid_equiv α β) : monoid_equiv (with_zero α) (with_zero β) := { to_fun := with_zero.map (h.to_equiv), inv_fun := with_zero.map (h.to_equiv.symm), left_inv := λ x, begin cases x, refl, show some _ = some _, congr, exact h.left_inv x end, right_inv := λ x, begin cases x, refl, show some _ = some _, congr, exact h.right_inv x end, mul_hom := λ x y, begin cases x; cases y, { refl}, { refl}, { refl}, { show some _ = some _, congr, exact h.mul_hom x y} end}
My plan for the proof of left_inv
was to use with_zero.map_comp
and with_zero.map_id
but there's barely any point.
Last updated: Dec 20 2023 at 11:08 UTC