Zulip Chat Archive
Stream: lean4
Topic: Why isn't Thunk a Monad?
François G. Dorais (Jan 16 2023 at 15:38):
It probably doesn't need to be a monad since it works pretty well as-is. However, I wonder if there is a reason why it shouldn't be a monad.
I noticed when I tried to write def foo : Thunk α := do ... but I realized that I needed to write def foo : Thunk α := Id.run do ... and rely on the coercion from α to Thunk α.
Kyle Miller (Jan 16 2023 at 15:45):
Of course it "is" a monad since there are docs4#Thunk.pure docs4#Thunk.bind (to be pedantic/annoying), but I'm also wondering if there's any reason there shouldn't be a Monad instance.
Relying on the coercion feels weird since it obscures when computations are happening.
François G. Dorais (Jan 16 2023 at 16:28):
I just checked that this works:
instance : Monad Thunk where
pure := Thunk.pure
bind := Thunk.bind
map := Thunk.map
instance : LawfulMonad Thunk where
map_const := by intros; rfl
id_map := by intros; rfl
bind_assoc := by intros; rfl
bind_pure_comp := by intros; rfl
bind_map := by intros; rfl
pure_bind := by intros; rfl
pure_seq := by intros; rfl
seqLeft_eq := by intros; rfl
seqRight_eq := by intros; rfl
So it really is a monad. There could still be issues related to the special support for Thunk in runtime which would make it ill-behaved.
Sebastian Ullrich (Jan 16 2023 at 16:33):
The compiler does not currently know anything about eliminating Thunk.pure _ >>= _. Which to be fair is mostly an issue if you then go on to define ThunkT and get implicit Thunk.pures from monad lifting everywhere.
Henrik Böving (Jan 16 2023 at 17:53):
We could easily add that as a rewrite rule for the new compiler :eyes:
François G. Dorais (Jan 16 2023 at 18:32):
So it would be mostly harmless and potentially useful to add. I made a quick PR to add it in Std.
Adrien Champion (Feb 29 2024 at 14:26):
@François G. Dorais I just re-did the exact same thing: Monad and LawfulMonad instances for Thunk. I'm not sure about what happened to your PR, I can't find a Monad Thunk instance anywhere (core/std/mathlib)
Adrien Champion (Feb 29 2024 at 14:26):
Is std still interested in a PR on this? I don't mind opening the PR
Adrien Champion (Feb 29 2024 at 14:29):
Also, as far as I can tell std mentions Thunk exactly thrice
Std/Data/MLList/Basic.lean
41: | thunk : Thunk (MLListImpl m α) → MLListImpl m α
Std/Tactic/Omega/Core.lean
310: explanation? : Thunk String := ""
352: explanation? := Thunk.mk fun _ => j.toString
Wouldn't it make more sense to have the Monad instance in core?
François G. Dorais (Mar 01 2024 at 23:36):
@Adrien Champion std4#88 suffered from bit rot so it was closed. I think it's better off in core since it needs compiler support to be useful.
Adrien Champion (Mar 03 2024 at 15:50):
I'm not clear on what you mean by "compiler support". I can open a similar PR to yours on core easily, but if I have to fiddle with internals for "compiler support" that's another story, would probably need some mentoring at least
Eric Wieser (Mar 03 2024 at 15:56):
François G. Dorais said:
Adrien Champion std4#88 suffered from bit rot so it was closed. I think it's better off in core since it needs compiler support to be useful.
Since getting things into core requires quite a strong motivation, would it make sense to have it reside in Std or Mathlib in the meantime?
François G. Dorais (Mar 03 2024 at 21:44):
The compiler issue was described by @Sebastian Ullrich in this thread. @Henrik Böving showed this will be easy to fix in the new compiler. I think the issue is that parts of the old compiler are basically frozen, so pure-bind elimination for Thunk will probably only happen in the new compiler.
Last updated: May 02 2025 at 03:31 UTC