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