如何实现依赖类型函子?求正确语法及可行方案
我明白你想要实现的是一个依赖于Element实例及其对应Wrapper实例的函子,用来封装特定场景下的定理。你当前的写法出问题是因为Wrapper E是具体模块,而Coq的函子参数要求指定模块类型,不是具体模块本身。下面是修正后的正确语法,分两种方案供你参考:
方案一:显式定义带参数的模块类型(推荐)
这种方式更清晰,能抽象出你需要的接口,不依赖具体实现:
# 首先定义Element模块类型,这里补个简单示例方便理解 Module Type Element. Parameter T : Type. Parameter eq : T -> T -> Prop. End Element. # 定义Wrapper的模块类型,它依赖于Element实例 Module Type WrapperType (E : Element). Parameter wrapped : Type. Parameter wrap : E.T -> wrapped. Parameter unwrap : wrapped -> E.T. End WrapperType. # 实现Wrapper函子,让它符合WrapperType接口 Module Wrapper (E : Element) <: WrapperType E. Definition wrapped := E.T. Definition wrap (x : E.T) := x. Definition unwrap (x : wrapped) := x. End Wrapper. # 现在可以正确定义依赖类型的函子了 Module DepentlyTypedFunctor (E : Element) (W : WrapperType E). (* 在这里定义你的场景相关定理,比如wrap/unwrap的互逆性 *) Theorem wrap_unwrap_consistent : forall x : W.wrapped, E.eq (W.unwrap (W.wrap (W.unwrap x))) (W.unwrap x). Proof. intros x. simpl. reflexivity. Qed. End DepentlyTypedFunctor.
方案二:直接引用现有模块的类型
如果你不想单独定义WrapperType,可以用module type of直接获取Wrapper E的模块类型:
Module DepentlyTypedFunctor (E : Element) (W : module type of Wrapper E). (* 同样可以在这里定义你的定理 *) Theorem unwrap_wrap_id : forall x : E.T, W.wrap (W.unwrap (W.wrap x)) = W.wrap x. Proof. intros x. simpl. reflexivity. Qed. End DepentlyTypedFunctor.
为什么原来的写法不行?
Coq的函子参数必须是模块类型,而你写的Wrapper E是把函子Wrapper应用到E后得到的具体模块,不是模块类型。通过上面两种方式,我们让W的类型依赖于E,实现了你想要的“依赖类型函子”效果——第二个参数的类型由第一个参数决定。
内容的提问来源于stack exchange,提问作者Mei Zhang
相关产品推荐
相关产品推荐

