Zulip Chat Archive
Stream: general
Topic: has_coe_to_fun questions
Kevin Buzzard (Oct 31 2018 at 15:34):
1) What's going on here?
import data.equiv.basic definition ABC : decidable_eq ℕ := by apply_instance theorem CBA : decidable_eq ℕ := by apply_instance definition XYZ (α β : Type) : has_coe_to_fun (α ≃ β) := by apply_instance -- theorem ZYX (α β : Type) : has_coe_to_fun (α ≃ β) := by apply_instance -- fails??
2) Does has_coe_to_fun
work by magic? I hadn't really appreciated this before. I understand how vanilla type class inference works, i.e. how has_add.add x y
uses unification to figure out the type of x and y and then uses type class inference to figure out what addition I meant, but the reason this works is that the definition of has_add.add
has some []
brackets in. I realise now that in this code
import data.equiv.basic example (α β : Type) (H : α ≃ β) : α → β := H
nothing I wrote contains a []
. So some extra magic is happening. Is this something to do with some C++ type unification algorithm going "oh-oh, H
doesn't have the right type, but the user is looking for a function, why don't I see if has_coe_to_fun
can help?" Or is there some more down-to-earth explanation which I've missed?
Johannes Hölzl (Oct 31 2018 at 15:43):
For 1) you see the difference when you activate set_option pp.all true
in the definition
case, the inferred function is into an type universe which is still a meta variable (which is important as it will be fixed to 1). In the theorem
case it is fixed to a universe variable, and hence fails
Johannes Hölzl (Oct 31 2018 at 15:44):
definition
does not require that the type is fully elaborated, quiet the opposite, that's why one can write a definition without a result type. The result type is inferred from the right-hand side.
Johannes Hölzl (Oct 31 2018 at 15:44):
theorem
works different, it fully elaborates the statement, and any universe hole is filled in with a fresh variable.
Floris van Doorn (Oct 31 2018 at 15:45):
2) Yes, there is some extra magic happening. If Lean knows that the type of some term t
is T
, and knows that the expected type is a function type, then it will automatically fire type-class inference to find an instance of has_coe_to_fun T
.
Johannes Hölzl (Oct 31 2018 at 15:48):
One might wonder why the universe parameters are not filled in by stating has_coe_to_fun (α ≃ β)
for α
and β
in Type 0
(which is the case in the examples):
has_coe_to_fun
actually allows to map to a different type universe!
Kevin Buzzard (Oct 31 2018 at 15:49):
Thanks to both of you. I remember it taking me a very long time to understand type class inference, and I had always assumed I understood it until I started thinking about it more carefully just the other day. For (1) I remember running into these subtleties with the difference between definition
and theorem
before, but maybe I have just never fully understood them. Usually they only show up (for me) when I foolishly use the wrong one :-) I think we should have a little VS Code paperclip that pops up saying "I see you're writing a theorem. Do you want some help with that, specifically because you seem to be constructing a term whose type is not a proposition?".
Last updated: Dec 20 2023 at 11:08 UTC