Zulip Chat Archive
Stream: lean4
Topic: Typeclass instance problem?
Joseph O (Mar 19 2022 at 14:47):
Why am I getting this error?
MWE:
inductive HList : List Type → Type 1 where
| nil : HList []
| cons {α : Type} (x : α) {αs : List Type} (xs : HList αs) : HList (α :: αs)
syntax (name := hlist) "[" term,* "]" : term
macro_rules (kind := hlist)
| `([]) => `(HList.nil)
| `([$x]) => `(HList.cons $x HList.nil)
| `([$x, $xs,*]) => `(HList.cons $x [$xs,*])
infixr:67 " :: " => HList.cons
def map {α : Type} {αs : List Type} (f : α → β) : HList (α::αs) → HList (β::αs)
| a::as => (f a)::as
instance : Functor (λ α => HList (α::αs)) where
map := HList.map
#eval let h : HList [Nat, String, Int] := [7, "hi", -2]; Functor.map (·*2) h
Error:
typeclass instance problem is stuck, it is often due to metavariables
Functor ?m.3922
Mario Carneiro (Mar 19 2022 at 14:49):
what instance are you expecting to find?
Joseph O (Mar 19 2022 at 14:50):
A functor instance?
Mario Carneiro (Mar 19 2022 at 14:50):
the use of Functor.map _ h
means that there should be an instance of Functor HList
Mario Carneiro (Mar 19 2022 at 14:51):
or rather, it would be that but this doesn't typecheck
Mario Carneiro (Mar 19 2022 at 14:51):
which is why the error is not even mentioning HList
Mario Carneiro (Mar 19 2022 at 14:51):
it has no idea what functor you are talking about
Sebastian Ullrich (Mar 19 2022 at 14:52):
In short, you cannot specify the functorial structure per-instance like this
Joseph O (Mar 19 2022 at 15:54):
Mario Carneiro said:
the use of
Functor.map _ h
means that there should be an instance ofFunctor HList
But i have such functor instance
Joseph O (Mar 19 2022 at 15:55):
Sebastian Ullrich said:
In short, you cannot specify the functorial structure per-instance like this
You mean like on the first item?
Mario Carneiro (Mar 19 2022 at 15:55):
No, you have Functor (λ α => HList (α::αs))
Mario Carneiro (Mar 19 2022 at 15:56):
Lean will not do the necessary higher order unification to find such instances
Mario Carneiro (Mar 19 2022 at 15:56):
If you want to use Functor
on a thing of type T A
then you need Functor T
, not Functor (id T)
or Functor (fun _ => T A)
or something else
Mario Carneiro (Mar 19 2022 at 15:58):
Alternatively, you could rewrite h
to have type (λ α => HList (α::[String, Int])) Nat
Mario Carneiro (Mar 19 2022 at 16:02):
Actually that doesn't seem to work either. It works if you specify f
explicitly:
#check
let h : HList [Nat, String, Int] := [7, "hi", -2]
Functor.map (f := λ α => HList [α, String, Int]) (·*2) h
Mario Carneiro (Mar 19 2022 at 16:05):
You can also make a definition for the type function and use that
def FirstList (αs α) := HList (α::αs)
instance : Functor (FirstList αs) where
map := HList.map
#check
let h : FirstList [String, Int] Nat := [7, "hi", -2]
Functor.map (·*2) h
Joseph O (Mar 19 2022 at 18:51):
Got it. So it seems there isn’t really a nice alternative.
Last updated: Dec 20 2023 at 11:08 UTC