Skip to content

feat: add a predicate for monad morphisms - #856

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

feat: add a predicate for monad morphisms#856
eric-wieser wants to merge 27 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.
These can be used to:
* replace the specialized timeM version
* implement sorts that log as they sort
* specialize to FreeM or PFunctor.FreeM
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
eric-wieser and others added 3 commits September 6, 2026 09:21
Co-authored-by: Fabrizio Montesi <fm@fabriziomontesi.com>
Comment thread Cslib/Foundations/Control/Monad/IsMonadHom/List.lean Outdated
Comment thread Cslib/Foundations/Data/PFunctor/Free.lean
Comment thread Cslib/Foundations/Control/Monad/IsMonadHom.lean
Comment thread Cslib/Foundations/Control/Monad/Free.lean
Comment thread Cslib/Foundations/Control/Monad/IsMonadHom/List.lean Outdated
Comment thread Cslib/Foundations/Control/Monad/IsMonadHom.lean Outdated
Comment thread Cslib/Foundations/Control/Monad/IsMonadHom/List.lean Outdated
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??

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.

set_option trace.grind.ematch.pattern true

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.

In particular grind . produces:

map_map:  [@Functor.map m _ α β g x,  @Functor.map n _ _ _ g _,  IsFunctorHom _ _ _ _ f]
map_pure: [@pure m _ α a,             @pure n _ _ a,             IsApplicativeHom _ _ _ _ f]
map_bind: [@bind m _ α β x k,         @bind n _ _ _ _ _,         IsMonadHom _ _ _ _ f]

but the proposed grind_patterns give:

map_map:  [IsFunctorHom m n f,     @Functor.map _ _ α β g x]
map_pure: [IsApplicativeHom m n f, @pure _ _ α a]
map_bind: [IsMonadHom m n f,       @bind _ _ α β x k]

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.

On second thoughts, maybe the proposed ones are too aggressive anyway. Without some actual proofs to try these out on, maybe it is premature optimization.

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 wasn't able to get either spelling to help with the proofs, so have left this as is for now.

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