C++的概念与Haskell的类型类有何不同?

41

C++概念从Concepts TS中提取后最近已经合并到GCC trunk。Concepts允许通过要求类型满足概念的条件(例如“可比较”)来限制通用代码。

Haskell拥有类型类。我不太熟悉Haskell。概念和类型类有什么关系?


概念是一种类型系统,用于当前未分类的元编程工具(一切都是“typename”,不考虑值参数)。类型类允许重载/选择函数,这取决于它们的参数类型。https://m.reddit.com/r/haskell/comments/1e9f49/concepts_in_c_template_programming_and_type/ 这可能是一个相关的讨论。 - Daniel Jour
2个回答

59
概念(由概念TS定义)和类型类仅在限制可与通用函数一起使用的类型集方面相关。除此之外,我只能想到这两个功能有所不同的方式。
我应该注意到我不是一个Haskell专家。远非如此。然而,我是概念TS的专家(我编写了它,并为GCC实现了它)。
· 概念(和约束)是确定类型是否为集合成员的谓词。您无需显式声明类型是否为概念模型(类型类的实例)。这由一组要求确定并由编译器检查。事实上,概念根本不允许您编写“T是C的模型”,尽管可以使用各种元编程技术轻松支持此功能。
· 概念可用于约束非类型参数,并且由于constexpr函数和模板元编程,几乎可以表达您希望编写的任何约束(例如,其范围必须是质数的哈希数组)。我不认为类型类也可以做到这一点。
· 概念不是类型系统的一部分。它们限制声明的使用,在某些情况下还涉及模板参数推断。类型类是类型系统的一部分,并参与类型检查。
· 概念不支持模块化类型检查或编译。模板定义未针对概念进行检查,因此在实例化期间仍可能出现延迟捕获类型错误,但这确实为库编写者增加了一定程度的灵活性(例如,向算法添加调试代码不会更改接口)。由于类型类是类型系统的一部分,因此可以模块化地检查和编译通用算法。
· 概念TS支持基于约束排序的通用算法和数据结构的专业化。我根本不是Haskell的专家,所以我不知道是否存在等效项。我找不到一个。
· 使用概念永远不会增加运行时成本。上次我看到,类型类可能会施加与虚拟函数调用相同的运行时开销,尽管我知道Haskell非常擅长优化这些开销。
我认为这些是比较功能(概念TS)与功能(Haskell类型类)之间的主要区别。
但是两种语言有一个根本的哲学差异 - 它不是函数式与您正在编写的任何C ++风味之间的差异。 Haskell希望成为模块化:成为模块化具有许多良好的属性。 C ++模板拒绝成为模块化:实例化时查找允许进行基于类型的优化而无需运行时开销。这就是为什么C ++通用库同时提供广泛的重用和无与伦比的性能的原因。

实际上,Haskell的模块化有一定的限制,因为它的编译过程严重依赖于内联和专门化以提高性能。如果修改了一个模块,所有导入它的模块都需要重新编译。有各种类型驱动优化技术(例如展开循环,针对数据结构大小由其类型固定等),还有一个相当复杂的用户定义的编译器重写规则系统。 - dfeuer
你有没有关于C++0x概念和Concepts TS之间差异的好参考资料?我曾经认为前者实现了模块化类型检查,那么可以假设这一点在Concepts TS中被放弃了吗? - Dominique Devriese
目前还没有很好的参考资料。C++0x概念与类型类并没有太大的区别。Concepts TS使用谓词来定义约束条件,并不包括模块化类型检查。 - Andrew Sutton
1
晚来的回复,但有一个小修正:据我所知,只要不使用存在量化,Haskell类型类就是编译时构造。更多细节请参见http://stackoverflow.com/questions/28169119/is-the-dispatch-of-a-haskell-typeclass-dynamic。 - iustin
作为一个实用主义者,如果涉及到Haskell类型类->C ++概念归结为1个问题:概念是否支持以下语句:“必须有一个函数''std :: string foo(const T&arg)”具有概念相关的参数类型列表。”关键是:我测试概念的第一个想法是拥有一个“概念显示”,它将像Haskell的“Show”类型类一样运作....然后开始阅读和搜索。此外,我记得当我开始学习Haskell时,在IRC中没有人意识到,旧风格的C ++接口可以在类型类的形式中找到。 - BitTickler

20
你可能对以下研究论文感兴趣:
《C++概念与Haskell类型类的比较》,Bernardy等人,WGP 2008。Pdf 更多详情
更新:作为论文的简要总结:该论文定义了C++概念术语和Haskell类型类术语之间的精确映射,并利用这种映射提供了两者之间的详细功能比较。
他们的结论如下:
在我们的27个标准中,总结在表2中,有16个标准在两种语言中都得到了支持,只有一两个标准不可移植。因此,我们可以安全地得出结论——C++概念和Haskell类型类非常相似。
正如T.C.所指出的,值得指出的是,该论文比较的是C++0x概念,而不是Concepts TS。我不知道有没有一个好的参考资料来描述它们之间的区别。

2
你能否从文献中添加一个专家吗?社区通常不赞成“仅链接”的问题! - recursion.ninja
1
@recursion.ninja 摘录? - jub0bs
7
@Jubobs,不,他应该在帖子中加入一位专家。他必须选取其中一位作者并将其数字化到他的文章中。我认为我说得很清楚 ;) - recursion.ninja
9
C++0x草案中的“概念”(被引用论文进行比较的)与“概念 TS”中的相当不同。 - T.C.
我已经尝试修复了到出版商版本的链接。对我来说,它已经可以正常工作了,但这可能是因为我在大学网络上。你能否检查一下是否需要付费才能访问? - undefined
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接