Zulip Chat Archive

Stream: new members

Topic: Need help converting code from 4.3.0 to 4.26.0


Kevin Cheung (Jan 28 2026 at 18:51):

I'm new to metaprogramming. I am trying to update some code written for 4.3.0 to 4.26.0. Below is the smallest example I could come up with that illustrates my problem:

import Mathlib.Tactic.Linarith

open Lean.Meta Qq Mathlib.Meta.NormNum

def foo (n : ) : Prop := n = 2

@[norm_num foo _ ] def evalFoo : NormNumExt where eval (e : Q(Prop)) := do
  let .app f (n : Q())  whnfR e | failure
  guard <|← withNewMCtxDepth <| isDefEq f q(foo)
  let rn : Result n  derive n
  let i : Q(Ring ) := q(Int.instRingInt)
  let zn, _, _⟩  rn.toInt
  sorry

Lean 4.3.0 was happy with the above, just highlighting the sorry as a warning.

My attempt to make it work in 4.26.0 first made me change Int.instRingInt to Int.instRing:

import Mathlib.Tactic.Linarith

open Lean.Meta Qq Mathlib.Meta.NormNum

def foo (n : ) : Prop := n = 2

@[norm_num foo _ ] def evalFoo : NormNumExt where eval (e : Q(Prop)) := do
  let .app f (n : Q())  whnfR e | failure
  guard <|← withNewMCtxDepth <| isDefEq f q(foo)
  let rn : Result n  derive n
  let i : Q(Ring ) := q(Int.instRing)
  let zn, _, _⟩  rn.toInt
  sorry

However, Lean 4.26.0 now gives an error right before sorry:

Type mismatch
  Result.toInt ?m.60 rn
has type
  Option ( × (lit : Q()) × Q(IsInt «$n» «$lit»))
but is expected to have type
  MetaM ?m.56

I cannot figure out what is wrong since the error is not present in the 4.3.0 version. Help greatly appreciated.

Aaron Liu (Jan 28 2026 at 19:02):

Do you understand what the error message is saying?

Kevin Cheung (Jan 28 2026 at 19:03):

I know there is a type mismatch. toInt is returning something that is not MetaM something.

Kevin Cheung (Jan 28 2026 at 19:03):

Otherwise, I'm baffled because I don't understand how the code could possibly work in 4.3.0.

Aaron Liu (Jan 28 2026 at 19:04):

Do you know what MetaM is?

Kevin Cheung (Jan 28 2026 at 19:04):

Only vaguely. It's a monad.

Aaron Liu (Jan 28 2026 at 19:06):

  let zn, _, _⟩  rn.toInt

In this snippet I can see that you are pulling out three elements from rn.toInt, which should be returning a monadic computation since we have the which means to run a monadic computation.

Kevin Cheung (Jan 28 2026 at 19:07):

Right. But somehow that was legal in 4.3.0.

Aaron Liu (Jan 28 2026 at 19:08):

From the error message I can see the actual type of rn.toInt is

  Option ( × (lit : Q()) × Q(IsInt «$n» «$lit»))

Aaron Liu (Jan 28 2026 at 19:08):

so there are still three values in there, but they are not behind a monadic computation anymore

Aaron Liu (Jan 28 2026 at 19:08):

instead, it's just an Option

Kevin Cheung (Jan 28 2026 at 19:08):

I just tried Gemini. It suggests let some ⟨zn, _, _⟩ := rn.toInt | failure

Aaron Liu (Jan 28 2026 at 19:09):

yes, that's what I would have suggested too

Kevin Cheung (Jan 28 2026 at 19:09):

So 4.3.0 must be doing something weird.

Aaron Liu (Jan 28 2026 at 19:10):

so probably what happened is that at some point the function was changed from being monadic to returning an Option value

Aaron Liu (Jan 28 2026 at 19:11):

and the reason your old code failed is because you are still using with your let which means "run this monadic computation and get the value out"

Aaron Liu (Jan 28 2026 at 19:11):

and that failed because rn.toInt isn't a monadic computation anymore

Kevin Cheung (Jan 28 2026 at 19:11):

I see.

Kevin Cheung (Jan 28 2026 at 19:12):

This is what I found in the old code:

def Result.toInt {α : Q(Type u)} {e : Q($α)} (_i : Q(Ring $α) := by with_reducible assumption) :
    Result e  Option ( × (lit : Q()) × Q(IsInt $e $lit))

Kevin Cheung (Jan 28 2026 at 19:12):

Doesn't seem monadic here.

Aaron Liu (Jan 28 2026 at 19:13):

then, I guess the other option is that there could've been a coercion to interpret a value of type Option as a MetaM computation, and this coercion was turned off

Kevin Cheung (Jan 28 2026 at 19:14):

I see. In any case, looks like my problem is solved. With the change, things seem to work now. Thanks.


Last updated: Feb 28 2026 at 14:05 UTC