Skip to content

feat: add a predicate for monad morphisms - #856

Open
eric-wieser wants to merge 9 commits into
leanprover:mainfrom
eric-wieser:monadHom
Open

feat: add a predicate for monad morphisms#856
eric-wieser wants to merge 9 commits into
leanprover:mainfrom
eric-wieser:monadHom

Conversation

@eric-wieser

@eric-wieser eric-wieser commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

We show that various list operations are preserved under monad morphisms, and that FreeM.liftM is.

Note that PolyFun already has the bundled version, but having the unbundled version now does not preclude adding the bundled version later.

We show that various list operations are monad morphisms, and that FreeM.liftM is.
@sorrachai sorrachai self-assigned this Sep 3, 2026
kim-em added a commit to kim-em/cslib that referenced this pull request Sep 5, 2026
The generic List.orderedInsertM/insertionSortM commute with any monad
morphism, stated with the IsMonadHom laws of
leanprover#856 inlined and needing no
lawfulness on either side. Since evaluation against an oracle is a monad
morphism to Id, the executable Id instantiation is List.insertionSort
with no separate proof about the generic definition, and the framework's
complexity bounds apply to the generic program definitionally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxy48TaP92UgEq28KGm8BG
Comment thread Cslib/Foundations/Control/Monad/IsMonadHom/List.lean Outdated
lemma liftM_map {α β : Type uB} (f : α → β) (x : P.FreeM α) :
(f <$> x).liftM interp = f <$> x.liftM interp := by
simp_rw [← LawfulMonad.bind_pure_comp, liftM_bind, liftM_pure]
lemma liftM_map {α β : Type uB} (f : α → β) (interp : (a : P.A) → m (P.B a)) (x : P.FreeM α) :

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
lemma liftM_map {α β : Type uB} (f : α → β) (interp : (a : P.A) → m (P.B a)) (x : P.FreeM α) :
lemma liftM_map {α β : Type uB} (f : α → β) (x : P.FreeM α) :

to match the argument order of the other lemmas.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the other lemmas have the wrong argument order, this matches the order for liftM itself.

Comment thread Cslib/Foundations/Control/Monad/IsMonadHom.lean
theorem Interprets.iff (handler : {ι : Type u} → F ι → m ι) (interp : FreeM F α → m α) :
Interprets handler interp ↔ interp = (·.liftM handler) :=
⟨(·.eq), fun h => h ▸ Interprets.liftM _⟩

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add

/-- A monad morphism out of `FreeM F` that agrees with `handler` on lifted operations is an
interpreter for `handler`, and hence (by `Interprets.eq`) equals `liftM handler`. -/
theorem _root_.Cslib.IsMonadHom.interprets {eval : ∀ {α}, FreeM F α → m α}
    (h : IsMonadHom (FreeM F) m eval)
    (handler : {ι : Type u} → F ι → m ι) (hl : ∀ {ι} (op : F ι), eval (lift op) = handler op)
    {α : Type u} : Interprets handler (eval : FreeM F α → m α) where
  apply_pure a := h.map_pure a
  apply_lift_bind op cont := by rw [h.map_bind, hl]

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not super happy with this Interprets API in the first place, so haven't spent much time thinking about how best to capture this. Can we punt this to a follow-up?

Comment thread Cslib/Foundations/Control/Monad/IsMonadHom/List.lean Outdated
Comment thread Cslib/Foundations/Control/Monad/IsMonadHom.lean Outdated
simpa [Subsingleton.elim (F ([] : List PEmpty)) []]
using (hf.map_map PEmpty.elim []).symm

protected theorem List.isMonadHom_reverse : IsMonadHom List List List.reverse :=

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is (accidentally?) in the CSLib namespace.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is deliberate, but if you think it's a bad idea I can move it back.

Comment thread Cslib/Foundations/Control/Monad/IsMonadHom.lean Outdated
namespace IsFunctorHom
variable {m n p : Type _ → Type _} [Functor m] [Functor n] [Functor p]

attribute [grind .] map_map map_mapConst

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

attribute [grind .] map_map map_mapConst

Maybe these grind patterns work better?

-- namespace IsFunctorHom
grind_pattern map_map => IsFunctorHom m n f, g <$> x
grind_pattern map_mapConst => IsFunctorHom m n f, Functor.mapConst a x

-- namespace IsApplicativeHom
grind_pattern map_pure => IsApplicativeHom m n f, (pure a : m α)
grind_pattern map_seq => IsApplicativeHom m n f, Seq.seq x y
grind_pattern map_seqLeft => IsApplicativeHom m n f, SeqLeft.seqLeft x y
grind_pattern map_seqRight => IsApplicativeHom m n f, SeqRight.seqRight x y

-- namespace IsMonadHom
grind_pattern map_bind => IsMonadHom m n f, x >>= y

-- namespace IsAlternativeHom
grind_pattern map_failure => IsAlternativeHom m n f, (Alternative.failure : m α)
grind_pattern map_orElse => IsAlternativeHom m n f, HOrElse.hOrElse x y

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do these compare to the patterns I already have? Can I print out the pattern generated by grind_pattern to compare with grind??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants