主要观点:
- 今日阅读关于幺半群的论文,发现 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) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。