Zulip Chat Archive
Stream: general
Topic: Monad Lifting
Mai (Jan 26 2026 at 00:27):
Why can't this automatically lift?
def foo : Option Nat := sorry
def bar : OptionT (StateM Nat) Nat := do
let _ <- foo
sorry
Jakub Nowak (Jan 26 2026 at 00:39):
Good question. There's ExceptT.instMonadLiftExcept but no lift for Option. Was it left on purpose or just was forgotten?
You can add it locally:
@[always_inline]
instance {m : Type u → Type v} [Monad m] : MonadLift Option (OptionT m) := ⟨fun e => OptionT.mk <| pure e⟩
def foo : Option Nat := do return 2
def bar : OptionT (StateM Nat) Nat := do
let _ <- foo
sorry
Aaron Liu (Jan 26 2026 at 00:40):
there's also docs#liftOption
Mai (Jan 26 2026 at 00:45):
Also, StateM Nat Nat doesn't seem to lift to StateT Nat Option Nat. Shouldn't it?
Chris Henson (Jan 26 2026 at 01:09):
Some earlier discussion here: #lean4 > `MonadLift Option (OptionT m)`
Mai (Jan 26 2026 at 01:16):
Would something like this make sense?
instance [Pure m] : MonadLift (StateM σ) (StateT σ m) where
monadLift m := pure ∘ m
Mai (Jan 26 2026 at 01:17):
I am pretty sure Id lifts into any monad
Mai (Jan 26 2026 at 08:31):
Or even a more extreme generalization?
instance [MonadLift m n] : MonadLift (StateT σ m) (StateT σ n) where
monadLift m σ := m σ
Mai (Jan 26 2026 at 08:32):
(The reasoning is that I would expect any automatic lifting in a do block to keep working after transforming the monad with StateT)
Mai (Jan 26 2026 at 09:34):
Oh no, Id isn't MonadLift, it's MonadLiftT... :cry:
Would this make sense?
instance [MonadLiftT m n] : MonadLiftT (StateT σ m) (StateT σ n) where
monadLift m σ := m σ
Last updated: Feb 28 2026 at 14:05 UTC