Zulip Chat Archive
Stream: new members
Topic: What effect does "instance" have in this example?
Kevin Cheung (Sep 24 2024 at 20:32):
I was just trying things and was surprised that the following compiled without warnings or errors:
import Mathlib.Data.Nat.Defs
instance bar : (n : ℕ) → Decidable (n = 1) := fun n => n.decEq 1
I am quite confused as to what instance
could possibly mean here. In particular, what is bar
an instance of?
Tom (Sep 24 2024 at 21:05):
My understanding is that an "instance" is a specific instantiation (value) of a type (class). These get registered with the elaborator and can be automatically found later during type class synthesis and as such, typically don't need a name, e.g.
instance : Add MyType where
is effectively converted to something like
def <elaboratorGeneratedName> : Add MyType := { ...fields... }
elaborator_magic.register_instance <elaboratorGeneratedName>
E.g.
instance myTypeAdd : Add MyType where
add x y := sorry
#reduce myTypeAdd
is { add := fun x y => sorryAx ?m.233 }
I think in this instance (ha!), it looks like your type is a function, so the instance is a value of a function type:
instance bar: (n : Nat) → Decidable (n = 1) := fun n => n.decEq 1
#reduce bar
is fun n => <snip>
You can try this by e.g. by
instance foo : Nat -> Nat := fun x => x + 1
#reduce foo
produces fun x => x.succ
So it seems instance
is just a "surface level"/Elaborator syntax for the above.
Unfortunately, I'm just a noob so don't know if
1) This/using functions has any implications on instance synthesis/registration (or whatever that may mean in this case)
2) I don't know whether the explicit name for the instance is useful beyond giving a name which is more "readable" to you
Tom (Sep 24 2024 at 21:08):
FWIW, I think the "registration magic" looks like this
attribute [instance] ...
Kyle Miller (Sep 24 2024 at 21:20):
(Terminology: "elaborator" instead of "compiler". There's a compiler too, but it's for turning elaborated declarations into executable code.)
Kevin Cheung (Sep 24 2024 at 21:25):
I am still trying to make sense of this. So instance
is basically attribute [instance]
before a def
? Does that mean that it can never fail?
Kyle Miller (Sep 24 2024 at 21:27):
Yes, instance foo ...
is pretty much @[instance] def foo ...
. If foo
isn't provided, it generates a name for you.
Could you say a bit more what you're confused about? Why did you expect it to fail?
Kevin Cheung (Sep 24 2024 at 21:27):
I thought an instance has to be associated with a class definition.
Kevin Cheung (Sep 24 2024 at 21:28):
In my example, no class was defined. So I wasn't sure what class the definition was an instance of.
Kyle Miller (Sep 24 2024 at 21:30):
docs#Decidable is a class, does that help?
Kevin Cheung (Sep 24 2024 at 21:31):
I can understand that if the part (n : Nat)
wasn't there.
Kevin Cheung (Sep 24 2024 at 21:32):
Something like instance : Decidable (1 = 1)
makes sense to me.
Kyle Miller (Sep 24 2024 at 21:34):
(Edit: This isn't quite right.) It turns out that (n : ℕ) → Decidable (n = 1)
is a class too. So long as the resulting value for a function type is a class, then it's a class. This class is parameterized by the variable n
. It applies to Decidable (0 = 1)
, Decidable (1 = 1)
, Decidable (2 = 1)
, etc.
Kyle Miller (Sep 24 2024 at 21:34):
Also, just like for normal definitions, both of these are equivalent:
instance bar (n : ℕ) : Decidable (n = 1) := n.decEq 1
instance bar : (n : ℕ) → Decidable (n = 1) := fun n => n.decEq 1
Kevin Cheung (Sep 24 2024 at 21:35):
So, it is a class that takes a parameter?
Kyle Miller (Sep 24 2024 at 21:35):
Yes. Many (most?) instances take parameters.
Kyle Miller (Sep 24 2024 at 21:36):
At least internally, (n : ℕ) → Decidable (n = 1)
is a class, but the class "is" Decidable
. Not sure if this phrasing helps at all.
Kevin Cheung (Sep 24 2024 at 21:36):
I guess I was confused by that Decidable
takes a Prop
and didn't know that Prop
can be parametrized.
Kyle Miller (Sep 24 2024 at 21:36):
Sorry, I'm really messing this up.
Kyle Miller (Sep 24 2024 at 21:37):
I'm meaning to say that the class is Decidable
, but (n : ℕ) → Decidable (n = 1)
is a valid type for an instance.
Kyle Miller (Sep 24 2024 at 21:37):
It's a parameterized instance.
Kevin Cheung (Sep 24 2024 at 21:37):
Interesting.
Kyle Miller (Sep 24 2024 at 21:40):
During instance synthesis, this corresponds to the rule that Decidable (_ = 1)
can always be satisfied, with any Nat in place of _
Tom (Sep 24 2024 at 22:02):
Kyle Miller said:
(Terminology: "elaborator" instead of "compiler". There's a compiler too, but it's for turning elaborated declarations into executable code.)
Thanks, fixed. I promised I'll start getting this right. :laughing:
Kevin Cheung (Sep 24 2024 at 22:29):
Thanks for the explanation. Very helpful.
Last updated: May 02 2025 at 03:31 UTC