我正在使用算法的Coq形式化。但是这个算法的组件(一些函数和引理)可以在不同类型上“重载”(在Haskell意义上)。
我的目的是避免代码重复。我知道Coq有模块(如ML)和类型类(如Haskell)。以这种方式实现对引用和函数定义的可重用性的最佳方法是什么?它可以在不同的类型上进行参数化?
答案 0 :(得分:3)
最好避免使用Coq模块执行除命名空间以外的任何操作或使定义不透明。依赖记录(类型类背后的基础特征)比编写参数化定义的模块更好,因为它们是可以通过适用于Coq中其他对象的相同规则操纵的第一类对象。话虽这么说,当将Coq代码提取到OCaml中时,Coq模块被提取到OCaml模块中,而依赖记录依赖于聪明的记录来正常工作。因此,如果您关心提取到OCaml,以及与提取的代码接口,模块可能是更好的选择。
类型类是一种基于依赖记录构建的功能,通过添加自动实例推断使其更易于使用。不幸的是,Coq中的类型类实例推断并不是非常强大,需要您调整实例或手动提供它们以使其在实践中工作 - 无论如何,它们肯定比Haskell对应物更难使用 - 并且还可以减慢编译时间。 MathClasses库在很大程度上依赖于类型类来定义数学结构,它似乎对它们有效。
还有另一个称为规范结构的功能,它也基于依赖记录,并且与类型类或多或少完全相同,但编程模型和推理引擎略有不同。在某些情况下,它们比类型类更好,但在其他情况下更难使用。例如,Ssreflect库广泛使用它们。
关于使用模块或记录here的讨论很少。