如何在定理类型中引用类型类多态变量?
How to reference type class-polymorphic variables in a theorem type?
我写了一个 Haskell 风格的 Functor
类型类:
Class Functor (f: Type -> Type) := {
map {a b: Type}: (a -> b) -> (f a -> f b);
map_id: forall (a: Type) (x: f a), map id x = x
}
其中 id
具有明显的定义。
现在,我已经为 list
和函数类型证明了 Functor
的实例。但我想证明关于 any 仿函数的陈述。首先,我想证明什么本质上是重言式:重述任何函子的 map_id
。
Theorem map_id_restatement: forall (F: Type -> Type),
Functor F -> forall T (x: F T), map id x = x.
为了证明这个定理,我会简单地 apply map_id
。但是当我尝试开始证明这一点时出现错误:
Toplevel input, characters 88-91:
Error:
Could not find an instance for "Functor F" in environment:
F : Type -> Type
T : Type
x : F T
但由于类型假设,Functor F
实例应该已经在范围内。为什么无法识别?
编辑:
好的,我发现我可以通过量化 Functor F
:
Theorem map_id_restatement: forall (F: Type -> Type) (finst: Functor F),
forall T (x: F T), map id x = x.
Proof. apply @map_id. Qed.
为什么这是必要的?有趣的是,如果我没有明确地为仿函数实例命名(即,如果我只写 (_: Functor F)
),它 不会 工作。
我不知道这是否是一个错误,但请注意,当您编写类似 Functor F -> SomeType
的内容时,您是在暗示 SomeType
不依赖于 [=16] =] 实例,这在你的情况下是不正确的:你的定理的完整类型,打印所有隐式参数,类似于:
Theorem map_id_restatement: forall (F: Type -> Type) (finst: Functor F),
forall T (x: F T), @map F fints T T (@id T) x = x.
如果将 finst
替换为 _
,则会得到
Theorem map_id_restatement: forall (F: Type -> Type) (_: Functor F),
forall T (x: F T), @map F _ T T (@id T) x = x.
这不能真正进行类型检查,因为 _
实际上不是一个变量名。
请注意,如果您在冒号前匿名绑定 Functor F
,Coq 会接受它:
Theorem map_id_restatement (F: Type -> Type) (_ : Functor F) :
forall T (x: F T), map (@id T) x = x.
Proof. apply @map_id. Qed.
据推测,这里 Coq 以不同的方式处理 _
,并用自动生成的名称替换它,而不是实际保留它未命名。您还可以使用以下形式,它在 forall
下或冒号前都有效:
Theorem map_id_restatement (F: Type -> Type) : forall `(Functor F),
forall T (x: F T), map (@id T) x = x.
Proof. apply @map_id. Qed.
我写了一个 Haskell 风格的 Functor
类型类:
Class Functor (f: Type -> Type) := {
map {a b: Type}: (a -> b) -> (f a -> f b);
map_id: forall (a: Type) (x: f a), map id x = x
}
其中 id
具有明显的定义。
现在,我已经为 list
和函数类型证明了 Functor
的实例。但我想证明关于 any 仿函数的陈述。首先,我想证明什么本质上是重言式:重述任何函子的 map_id
。
Theorem map_id_restatement: forall (F: Type -> Type),
Functor F -> forall T (x: F T), map id x = x.
为了证明这个定理,我会简单地 apply map_id
。但是当我尝试开始证明这一点时出现错误:
Toplevel input, characters 88-91:
Error:
Could not find an instance for "Functor F" in environment:
F : Type -> Type
T : Type
x : F T
但由于类型假设,Functor F
实例应该已经在范围内。为什么无法识别?
编辑:
好的,我发现我可以通过量化 Functor F
:
Theorem map_id_restatement: forall (F: Type -> Type) (finst: Functor F),
forall T (x: F T), map id x = x.
Proof. apply @map_id. Qed.
为什么这是必要的?有趣的是,如果我没有明确地为仿函数实例命名(即,如果我只写 (_: Functor F)
),它 不会 工作。
我不知道这是否是一个错误,但请注意,当您编写类似 Functor F -> SomeType
的内容时,您是在暗示 SomeType
不依赖于 [=16] =] 实例,这在你的情况下是不正确的:你的定理的完整类型,打印所有隐式参数,类似于:
Theorem map_id_restatement: forall (F: Type -> Type) (finst: Functor F),
forall T (x: F T), @map F fints T T (@id T) x = x.
如果将 finst
替换为 _
,则会得到
Theorem map_id_restatement: forall (F: Type -> Type) (_: Functor F),
forall T (x: F T), @map F _ T T (@id T) x = x.
这不能真正进行类型检查,因为 _
实际上不是一个变量名。
请注意,如果您在冒号前匿名绑定 Functor F
,Coq 会接受它:
Theorem map_id_restatement (F: Type -> Type) (_ : Functor F) :
forall T (x: F T), map (@id T) x = x.
Proof. apply @map_id. Qed.
据推测,这里 Coq 以不同的方式处理 _
,并用自动生成的名称替换它,而不是实际保留它未命名。您还可以使用以下形式,它在 forall
下或冒号前都有效:
Theorem map_id_restatement (F: Type -> Type) : forall `(Functor F),
forall T (x: F T), map (@id T) x = x.
Proof. apply @map_id. Qed.