Zulip Chat Archive
Stream: new members
Topic: Declaring canonical instance of typeclass?
cbailey (Mar 09 2019 at 21:14):
If I have a typeclass with a funciton f : A -> B , and for any argument type A it will have at most one instance declared, is there a way to mark it so that I don't have to annotate the return type at the call site? As an artificial example:
-- class provides one function f mapping α to some representation class to_representable (α : Type) {β : Type} [has_repr β] := (f : α → β) def nat_to_string : ℕ → string := (λ n : ℕ, "I am a nat") def int_to_list : ℤ → list ℤ := (λ z : ℤ, [z]) -- These will be the only instances of this typeclass for nat and int respectively instance : to_representable ℕ := ⟨ nat_to_string ⟩ instance : to_representable ℤ := ⟨ int_to_list ⟩ open to_representable -- Have to call like this, explicitly passing β def with_type1 := f string (999 : ℕ) def with_type2 := f (list ℤ) (1 : ℤ) -- Want to be able to call like this def without_type1 := f (999 : ℕ) -- type mnismatch application... def without_type2 := f (1 : ℤ)
Kevin Buzzard (Mar 09 2019 at 21:15):
Well we were just talking about the dangers of this in another thread, but you could move beta into the class as a field I guess
Mario Carneiro (Mar 09 2019 at 21:25):
-- class provides one function f mapping α to some representation class to_representable (α : Type) := (β : Type) [r : has_repr β] (to_fun : α → β) def to_representable.f {α} [to_representable α] : α → to_representable.β α := to_representable.to_fun def nat_to_string : ℕ → string := (λ n : ℕ, "I am a nat") def int_to_list : ℤ → list ℤ := (λ z : ℤ, [z]) -- These will be the only instances of this typeclass for nat and int respectively instance : to_representable ℕ := ⟨_, nat_to_string⟩ instance : to_representable ℤ := ⟨_, int_to_list⟩ open to_representable -- Want to be able to call like this def without_type1 := f (999 : ℕ) def without_type2 := f (1 : ℤ)
Mario Carneiro (Mar 09 2019 at 21:26):
alternatively, with out_param
:
-- class provides one function f mapping α to some representation class to_representable (α : Type) (β : out_param Type) [out_param (has_repr β)] := (to_fun : α → β) def to_representable.f {α β} [has_repr β] [to_representable α β] : α → β := to_representable.to_fun def nat_to_string : ℕ → string := (λ n : ℕ, "I am a nat") def int_to_list : ℤ → list ℤ := (λ z : ℤ, [z]) -- These will be the only instances of this typeclass for nat and int respectively instance : to_representable ℕ _ := ⟨nat_to_string⟩ instance : to_representable ℤ _ := ⟨int_to_list⟩ open to_representable -- Want to be able to call like this def without_type1 := f (999 : ℕ) def without_type2 := f (1 : ℤ)
cbailey (Mar 09 2019 at 21:28):
I was just about to ask what the syntax was to shoehorn the typeclass constraint in there. This is perfect.
cbailey (Mar 09 2019 at 21:28):
@Kevin Buzzard You mean the danger for the consumers of the API?
Mario Carneiro (Mar 09 2019 at 21:28):
I cheated a bit in the first version, because everything is in Type 0
Mario Carneiro (Mar 09 2019 at 21:29):
when you allow for universes the free universe argument for beta can cause problems
Mario Carneiro (Mar 09 2019 at 21:30):
but at least with the stuff in the example, everything works without incident if you put universes in as in
universes u v class to_representable (α : Type u) := (β : Type v) [r : has_repr β] (to_fun : α → β)
cbailey (Mar 09 2019 at 21:31):
I'll keep that in mind. What exactly is out_param? I've seen it here and there, but searching the lean repo wasn't terribly enlightening.
Mario Carneiro (Mar 09 2019 at 21:31):
searching the chat will have better results
cbailey (Mar 09 2019 at 21:32):
Word.
Kevin Buzzard (Mar 09 2019 at 21:39):
https://gitter.im/leanprover_public/Lobby?at=5a6e31685a9ebe4f75e77351
Kevin Buzzard (Mar 09 2019 at 21:39):
searching the old chat has the best results :-)
cbailey (Mar 09 2019 at 21:51):
Oh, nice. I didn't even know there was an old chat.
Kevin Buzzard (Mar 09 2019 at 21:52):
please don't post anything there :-)
Kevin Buzzard (Mar 09 2019 at 21:52):
we all got bored of going back once a month saying "we're now at the new chat"
Last updated: Dec 20 2023 at 11:08 UTC