Zulip Chat Archive
Stream: lean4
Topic: Use just-defined instance of substructure in superstructure?
Thomas Murrills (Mar 14 2023 at 03:19):
Consider the following #mwe:
class Foo (α : Type) where
x : Bool
def f (α) [Foo α] : Nat := 0
class Bar (α : Type) extends Foo α where
y : f α = 0
theorem fIsZero (α) [Foo α] : f α = 0 := rfl
def baz : Bar Nat := { x := true, y := fIsZero Nat} -- failed to synthesize instance
Foo ℕ
We've just defined an instance of Foo Nat
by providing x
, but fIsZero
can't see it.
How do we get something like fIsZero
to use the Foo α
we've just defined? Is there a better option than just "precariously" inlining an instance of Foo Nat
which happens to be equal to the one we're defining?
Adam Topaz (Mar 14 2023 at 03:24):
you could do this:
def baz : Bar Nat :=
let t : Foo Nat := ⟨true⟩
{ t with y := fIsZero Nat}
Thomas Murrills (Mar 14 2023 at 04:07):
Nice, thanks!
Jireh Loreaux (Mar 14 2023 at 05:11):
Don't you want to use letI
so that it actually gets inlined?
Thomas Murrills (Mar 14 2023 at 05:32):
Ok, sounds good—but just wondering, what's the actual difference, there? Why would I want let
to not inline sometimes? (Or when can it not?)
Reid Barton (Mar 14 2023 at 06:43):
Usually you don't want let
to inline, to avoid computing something more than once, or to avoid blowing up the term size.
Adam Topaz (Mar 14 2023 at 16:28):
Jireh Loreaux said:
Don't you want to use
letI
so that it actually gets inlined?
Yes, letI
would be better here. I only used let
because I wasn't sure whether Thomas wanted to rely on std4 (which is where letI
is defined)
Last updated: Dec 20 2023 at 11:08 UTC