Zulip Chat Archive

Stream: lean4

Topic: Is Std.Internal.IO.Async.MonadAsync.toMonad a bad instance?


Eric Wieser (Aug 28 2025 at 08:56):

docs#Std.Internal.IO.Async.MonadAsync seems to break the rule of "a 2-ary typeclass should never extend a 1-ary one", as there is no way to determine what t should be used to find Monad m from MonadAsync t m:

Std.Internal.IO.Async.MonadAwait.toMonad (t : Type  Type) {m : Type  Type}
  [self : Std.Internal.IO.Async.MonadAwait t m] : Monad m

Eric Wieser (Aug 28 2025 at 08:57):

You can see this blow-up in action (on mathlib stable or the latest mathlib) in:

import Lake.Load.Resolve
import Std.Internal.Async.Basic

open Lake

variable {m} [Monad m] [MonadError m]

#synth MonadWorkspace (ResolveT m)

Eric Wieser (Aug 28 2025 at 08:57):

docs#Std.Internal.IO.Async.MonadAwait seems similarly bad

Eric Wieser (Aug 28 2025 at 09:10):

"the rule" I mention is the one in #mil; I've created https://github.com/avigad/mathematics_in_lean_source/pull/316 to track that the error message it reports seems to no longer occur.

Eric Wieser (Aug 28 2025 at 11:37):

cc @Anne Baanen, since I think your thesis discusses such instances

Anne Baanen (Aug 28 2025 at 12:42):

Yes, such extends clauses cause underdetermined instances, and would generally be a bad idea unless t is a (semi)outparam. Normally this should cause an error "cannot find synthesization order for instance ... all remaining arguments have metavariables". Indeed if I make a declaration with the same type I see the error. Weird that the check does not seem to fire on the definition of MonadAsync.

Eric Wieser (Aug 28 2025 at 13:01):

cannot find synthesization order for instance ... all remaining arguments have metavariables

This error no longer files if you define Module this way either:

import Mathlib

class Module' (R : Type) [Ring R] (M : Type) extends AddCommGroup M, SMul R M where
  zero_smul :  m : M, (0 : R)  m = 0
  one_smul :  m : M, (1 : R)  m = m
  mul_smul :  (a b : R) (m : M), (a * b)  m = a  b  m
  add_smul :  (a b : R) (m : M), (a + b)  m = a  m + b  m
  smul_add :  (a : R) (m n : M), a  (m + n) = a  m + a  n

Jovan Gerbscheid (Aug 28 2025 at 16:56):

I was working on a fix for this type class issue in lean#9638 (see also #lean4 > projection instance binderinfo problem ). And on the toolchain of that PR, the definition of MonadAwait indeed throws an error.

But the strange thing is that the CI on the PR was green, so I didn't notice this bad instance (I did notice some in Batteries and Mathlib). Is this some sort of bootstrapping thing where it doesn't do a second build?

Jovan Gerbscheid (Aug 28 2025 at 17:02):

The lack of this error message was introduced by lean#5376

Jovan Gerbscheid (Aug 28 2025 at 17:03):

Anyways, in this case I think the t argument in MonadAsync and MonadAwait should be a semiOutParam.

Robin Arnez (Aug 28 2025 at 22:06):

I'd actually argue that we shouldn't extend Monad in the first place but use [Monad m] - take something like
docs#Std.Internal.IO.Async.concurrentlyAll which already says [Monad m] [MonadAwait t m] [MonadAsync t m] which would be three different monad instances!

Jovan Gerbscheid (Aug 28 2025 at 22:19):

It has [MonadAwait Task m] [MonadAsync t m] [MonadAwait t m] [Monad m], so I'm counting 4 different monad instances :laughing:

But yes, if we ever want to combine [MonadAsync t m] and [MonadAwait t m], then these classes should certainly not extend Monad m.

Henrik Böving (Aug 29 2025 at 08:08):

CC @Sofia Rodrigues

Sofia Rodrigues (Aug 29 2025 at 14:42):

I opened PR #10173 that removes extends Monad from both type classes.

Eric Wieser (Aug 29 2025 at 14:50):

Probably it should be backported, since I assume these bad instances can impact more than just lake

Markus Himmel (Aug 29 2025 at 15:30):

Are you actively affected by this?

Eric Wieser (Aug 29 2025 at 15:37):

I don't know yet, but my understanding is that a backport (at least to 4.23.0) is as simple as adding a label

Eric Wieser (Aug 29 2025 at 15:37):

I understand backporting to 4.22.0 is more work

Markus Himmel (Aug 29 2025 at 15:42):

It's as simple as adding a label as long as you don't need an rc3.

Eric Wieser (Aug 29 2025 at 15:47):

I guess I'd advocate putting it on the branch in case something _else_ justifies a new RC release

Markus Himmel (Aug 29 2025 at 15:48):

Already done :)

Eric Wieser (Aug 29 2025 at 15:48):

What should the action be on https://github.com/avigad/mathematics_in_lean_source/pull/316 ?

Eric Wieser (Aug 29 2025 at 15:48):

Is the error message supposed to be produced?

Jovan Gerbscheid (Aug 29 2025 at 15:50):

Yes, the error message is supposed to be produced. This is part of the problem I wanted to fix.


Last updated: Dec 20 2025 at 21:32 UTC