Zulip Chat Archive
Stream: lean4
Topic: Lean.Core.wrapAsync and MonadControl
Eric Wieser (Jan 08 2025 at 20:25):
I found myself wanting wrapAsync
for MetaM
. While it's easy to write this by hand by getting the state and context, I was wondering if using controlAt
is appropriate here:
import Lean
open Lean Meta
@[inherit_doc Core.wrapAsync]
def Lean.Meta.wrapAsync (act : Unit → MetaM α) : MetaM (EIO Exception α) := do
controlAt CoreM fun run =>
Core.wrapAsync fun x => do
run <| act x
Eric Wieser (Jan 08 2025 at 20:34):
Is this the same as:
@[inherit_doc Core.wrapAsync]
def Lean.Meta.wrapAsync2 (act : Unit → MetaM α) : MetaM (EIO Exception α) := do
let metaCtx ← readThe Meta.Context
let metaSt ← getThe Meta.State
Core.wrapAsync fun _ =>
act () |>.run' metaCtx metaSt
or is there some ST.Ref
trickery here with multiple threads?
Eric Wieser (Jan 08 2025 at 20:42):
If I attempt to equate them with
example : @_root_.Lean.Meta.wrapAsync = @Lean.Meta.wrapAsync2 := by
unfold Lean.Meta.wrapAsync Lean.Meta.wrapAsync2 readThe getThe controlAt instMonadReaderOfReaderTOfMonad
instMonadControlStateRefT' instMonadControlReaderT instMonadStateOfOfMonadLift
instMonadControlTOfMonadControl liftWith instMonadControlTOfPure Function.comp inferInstanceAs instMonadLiftTOfMonadLift
instMonadMetaM StateRefT'.instMonad inferInstanceAs ReaderT.instMonad ReaderT.read ReaderT.bind liftM ReaderT.instMonadLift
StateRefT'.instMonadLift StateRefT'.lift Core.instMonadCoreM inferInstanceAs StateRefT'.instMonad ReaderT.instMonad ReaderT.bind
StateRefT'.instMonadStateOfOfMonadLiftTST StateRefT'.get inferInstanceAs instMonadEIO EStateM.instMonad inferInstanceAs EStateM.bind
dsimp [Pure.pure, ReaderT.pure, EStateM.pure]
ext α f ctx st mctx mst w
rfl
I see that the state is
α : Type
f : Unit → MetaM α
ctx : Context
st : ST.Ref IO.RealWorld State
mctx : Core.Context
mst : ST.Ref IO.RealWorld Core.State
w : IO.RealWorld
⊢ (match Core.wrapAsync (fun x => f x ctx st) mctx mst w with
| EStateM.Result.ok a s => EStateM.Result.ok a s
| EStateM.Result.error e s => EStateM.Result.error e s) =
match st.get mctx mst w with
| EStateM.Result.ok a s => Core.wrapAsync (fun x => (f ()).run' ctx a) mctx mst s
| EStateM.Result.error e s => EStateM.Result.error e s
Sebastian Ullrich (Jan 09 2025 at 09:18):
The MonadControl
instance for StateRefT'
is derived from ReaderT
so I'm quite sure it's not suitable for multithreading
Last updated: May 02 2025 at 03:31 UTC