主要观点:
- 今日阅读关于幺半群的论文,发现 Haskell 标准库旧版本的有趣缺陷,借此记录思考。
- 介绍了 Haskell 中的幺半群(Monoid)和半群(Semigroup),及它们的定义和关系。
- 指出标准库中
Monoid (Maybe a)的实例定义存在问题,应使用Semigroup a => Monoid (Maybe a),此问题在base-4.11中得到修复。 - 强调设计通用的库更难,以解析库为例,需考虑多种输入类型,如 megaparsec 库使用
Stream类型类。 - 提及许多库都存在改进空间,如 Haskell 前奏中的
head、JavaScript 的日期 API、Python 的标准库提案、Xorg 的 API 和安全问题等,库会不断演进,有时需要破坏式更改。
关键信息:
Monoid有单位元mempty和组合函数mappend,Semigroup有mappend但不一定有mempty,任何Monoid也是Semigroup。Maybe a可通过将Nothing作为单位元变成Monoid (Maybe a),标准库中Monoid (Maybe a)的实例定义存在不足。- 设计库要确定最小约束使库能工作,库的演进可能需要破坏式更改,基于纯遗留原因的 API 可能导致膨胀。
重要细节:
- 文中给出
Monoid和Semigroup的实例定义代码,如instance Monoid (List a) where...等。 - 提到
Data.Semigroup模块及Option数据类型,它是Maybe的更好实例。 - 以 megaparsec 库的
Stream类型类为例说明设计通用库的考虑。 - 列举多个库存在改进空间的例子,如 Haskell、JavaScript、Python、Xorg 等。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。