Zulip Chat Archive

Stream: lean4

Topic: How to lift a monad instance?


StructSeeker (Nov 06 2025 at 09:07):

The following quite natural code can't compile

def foo [Monad m] [MonadReader Nat m] [MonadExcept String m]: m Bool := do
  pure ((<- read) > 4)

def bar [Monad m] [MonadExcept String m]: m Bool := do
  let env : Nat := 2
  ReaderT.run (foo (m:= ReaderT Nat m)) env

I receive the following alert

failed to synthesize
  MonadExcept String (ReaderT Nat m)

Do i need to implement a instance manually whenever i meet this kind of situation?
I ask AI but unable to obtain a satisfactory answer.

Aaron Liu (Nov 06 2025 at 11:05):

Why do you think you should be able to read a Nat out of ReaderT Bool m?

StructSeeker (Nov 06 2025 at 11:10):

Aaron Liu
Sorry, i mistyped when trying to create a minimal example. But I still can't solve the problem.

Eric Wieser (Nov 06 2025 at 11:10):

I think we're missing a MonadExcept instance for ReaderT

Eric Wieser (Nov 06 2025 at 11:12):

instance [MonadExcept ε m] : MonadExcept ε (ReaderT ρ m) where
  throw e := fun _ => throw e
  tryCatch body handler := fun x => tryCatch (body x) (handler · x)

Eric Wieser (Nov 06 2025 at 11:14):

I'm quite surprised this is missing; was it removed accidentally recently?

Eric Wieser (Nov 06 2025 at 11:15):

Ah, it's docs#ReaderT.instMonadExceptOf

Eric Wieser (Nov 06 2025 at 11:15):

I think you're not supposed to assume MonadExcept, and to use MonadExceptOf isntead?


Last updated: Dec 20 2025 at 21:32 UTC