据我所知,Coq中的一个类型是"几乎"一个记录,带有魔法周围的类型推断。
虽然我不知道有人明确说过,但我觉得类型类可以做任何记录都可以做的事情。
然而,这种感觉导致我遇到类型类访问器的一些问题,这似乎是记录的标准:
Require Import List.
Set Printing All.
Set Implicit Arguments.
(* Record version that works: *)
Record Foo_r (A_r: Type) := { getter_r : list A_r; }.
Definition foo_r : Foo_r nat := {| getter_r := 2::nil |}.
Compute (getter_r foo_r).
(* Type class version that does not work: *)
Class Foo_t (A_t: Type) := { getter_t : list A_t; }.
Instance foo_t : Foo_t nat := {| getter_t := 2::nil |}.
Compute (getter_t foo_t).
有趣的是, getter_r 和 getter_t 具有非常相似的功能签名,并且 Foo_t 确实只是一个记录:< / p>
Print getter_r.
(* fun (A_r : Type) (f : Foo_r A_r) => let (getter_r) := f in getter_r
: forall A_r : Type, Foo_r A_r -> list A_r *)
Print getter_t.
(* fun (A_t : Type) (Foo_t0 : Foo_t A_t) => let (getter_t) := Foo_t0 in getter_t
: forall A_t : Type, Foo_t A_t -> list A_t *)
我可以问一下,从概念上讲,这是一个禁止类型类访问者的设计决定吗?或者我只是用错了?感谢。
答案 0 :(得分:4)
如果您使用getter_t
检查About getter_t.
的类型,您会看到:
getter_t : forall (A_t : Type) (_ : Foo_t A_t), list A_t Arguments A_t, Foo_t are implicit and maximally inserted
Foo_t
最大插入,这意味着如果您只提及getter_t
没有更多信息,Coq应该能够推断出这种类型的参数。换句话说,说
Compute getter_t foo_t.
与
相同Compute @getter_t _ _ foo_t.
这是不正确的,因为@getter_t
只接受两个参数(@
- 符号表示&#34;我将列出所有参数,包括隐含的参数&#34;)
你可以说
Compute @getter_t _ foo_t.
或者只是
Compute getter_t.