Zulip Chat Archive

Stream: lean4

Topic: Type inference failure


Jovan Gerbscheid (Dec 18 2023 at 13:17):

I encountered a piece of code where I believe Lean should be able to infer the types, but it isn't able to. Here's a minimised version:

def f (a : α) : α := Id.run do
  let (b) 
    (fun _ => do
      if true then pure () else pure ()
      return a
      ) ()
  -- invalid match-expression, type of pattern variable 'b' contains metavariables
  -- ?m.494
  return b

It can be fixed by removing the brackets around b, because with the brackets it is interpreted as a pattern, but this fix doesn't work if you're working with a non-trivial pattern like this:

def f (a : α) : α := Id.run do
  let (b, _) 
    (fun _ => do
      if true then pure () else pure ()
      return (a,a)
      ) ()
  return b

Eric Wieser (Dec 18 2023 at 14:12):

This works fine:

def f (a : α) : α := Id.run do
  let (b)  do
    if true then pure () else pure ()
    pure a
  return b

Jovan Gerbscheid (Dec 18 2023 at 14:26):

I went a bit far with minimizing the example, what about this:

def f (a : α) (A : Array Unit) : Option α := do
  let (b)  A.foldr (init := none) fun _ x => (do
    if true then pure () else pure ()
    return a
    ) <|> x
  return b

Jovan Gerbscheid (Dec 18 2023 at 14:28):

By the way, the problem can be solved by writing an extra type annotation somewhere, but it is quite frustrating to get an error message and to need to "fix" a piece of code when it is perfectly valid.

Kyle Miller (Dec 18 2023 at 15:27):

Weird, adding a variable line gets rid of the error, and adding {α : Type _} as an extra argument doesn't suffice.

variable {α : Type _}

def f (a : α) (A : Array Unit) : Option α := do
  let (b)  A.foldr (init := none) fun _ x => (do
    if true then pure () else pure ()
    return a
    ) <|> x
  return b

Eric Wieser (Dec 18 2023 at 15:47):

(not that it's really {α : Type} here, since the Unit forces everything to live in Type 0)

Jovan Gerbscheid (May 24 2024 at 14:56):

Here is another type inference failure, this time in the presence of a type class diamond, which causes trySynthInstance to return .none instead of .undef. This causes the expected type to not be propagated properly.

class AA (α : Type) where
  asNum : α  Nat
  p : α  Prop

class AB (α : Type) extends AA α
class BA (α : Type) extends AA α
class BB (α : Type) extends AB α, BA α

class X (α : Type) (f : α  Nat)

instance [AB α] : X α AA.asNum where

theorem X_rfl [BA α] [X α AA.asNum] {a : α} : AA.p a  AA.p a := Iff.rfl

/-
failed to synthesize instance
  X ?m.234 AA.asNum
-/
example {α : Type} [BB α] (a : α) : AA.p a  AA.p a := X_rfl.mpr

Last updated: May 02 2025 at 03:31 UTC