Hackage 有几个用于 monad 转换器的包:
mtl: Monad 转换器库
变压器:具体函子和单子变压器
monads-fd:Monad 类,使用函数依赖
monads-tf:Monad 类,使用类型族
monadLib:monad 转换器的集合。
mtl-tf:使用类型族的 Monad 转换器库。
mmtl:模块化 Monad 变压器库
mtlx:具有类型索引的 Monad 转换器库,提供“免费”副本。
compose-trans:可组合的 monad 转换器
(也许我错过了一些)
我们应该使用哪一个?
mtl 是 Haskell 平台中的一个,但我一直在 reddit 上听到它不酷。
但是无论如何选择有什么不好的,这不只是一件好事吗?
好吧,我看到了例如 data-accessor 的作者如何不得不做出所有这些来迎合流行的选择:
data-accessor-monadLib 库:monadLib 的 monad 的访问器函数
data-accessor-monads-fd 库:使用 Accessor 访问 monads-fd State monad 类中的状态
data-accessor-monads-tf 库:使用 Accessor 访问 monads-tf State monad 类型族中的状态
data-accessor-mtl 库:使用 Accessor 访问 mtl State monad 类中的状态
data-accessor-transformers 库:使用 Accessor 访问变压器状态单子中的状态
我想如果这种情况继续下去,例如几个相互竞争的 Arrow 包演变,我们可能会看到类似的东西:spoonklink-arrows-transformers、spoonklink-arrows-monadLib、spoonklink-tfArrows-transformers、spoonklink-tfArrows-monadLib,...
然后我担心如果spoonklink 被分叉,Hackage 会耗尽磁盘空间。 :)
问题:
为什么有这么多单子变压器包?
为什么 mtl [认为] 不酷?
主要区别是什么?
大多数这些看似相互竞争的软件包都是由 Andy Gill 编写的,并由 Ross Paterson 维护。这是否意味着这些软件包不是相互竞争而是以某种方式协同工作? Andy 和 Ross 是否认为他们自己的软件包已经过时?
你和我应该使用哪一个?
其中一堆几乎完全等价:
mtl 使用 GHC 扩展,但转换器是 Haskell 98。
monads-fd 和 monads-tf 是转换器的附加组件,分别使用函数依赖和类型族,两者都提供了转换器中缺少的 mtl 功能。
mtl-tf 是使用类型族重新实现的 mtl。
所以本质上,mtl
== transformers
++ monads-fd
,mtl-tf
== transformers
++ monads-tf
。我认为,transformers
及其相关软件包的改进的可移植性和模块化是 mtl
现在不酷的原因。
mmtl
和 mtlx
似乎都与 mtl
相似和/或基于 mtl
,但有 API 差异和额外功能。
MonadLib
似乎对事情有相当不同的看法,但我并不直接熟悉它。似乎也使用了很多 GHC 扩展,比其他扩展更多。
乍一看,compose-trans
似乎更像是用于创建 monad 转换器的元编程材料。它声称与 Control.Monad.Trans
兼容...我猜这意味着 mtl
?
无论如何,我建议使用以下决策算法:
你需要一个新项目的标准单子吗?使用transformers & co.,帮助我们让mtl休息。
您是否已经在大型项目中使用 mtl?变压器并不完全兼容,但没有人会因为不切换而杀死你。
其他软件包之一是否提供了您需要的不寻常功能?还不如使用它而不是自己滚动。
还是不满意?把它们全部扔掉,下载额外的类别,用一页半难以理解的抽象废话惊人的通用代码解决世界上所有的问题。
暂时?您可能应该使用 mtl
。正在发生的事情是 transformers
库以 monads-fd
和 monads-tf
可以和平共存的方式从 MTL 中分离出来,但最后检查情况并非如此。
发生这种情况时,您将能够导入 monads-fd
和 transformers
并获得(几乎)相同的界面,除了 State
等将成为 StateT
的别名。
所以我会写信给 mtl
,但不要依赖 State、Reader 等当前是 data
的事实,因为它们将被 type
替换。
MonadLib
是 Iavor 一直在研究的另一种替代方案,可以安全使用,因为它不与其他模块共享任何模块名称,但使用模式完全不同。
transformers
&公司但是,在切换一些(相当简单的)代码时,除了一些小的 API 差异与 mtl
之外,没有注意到任何问题。
Edward Kmett 在 his answer 中提到的分解已于 2010 年底完成。其最终结果是 monads-fd,基于 transformers,成为 mtl 的第 2 版。由于 mtl 无处不在,monads-tf 从未真正流行起来。截至 2017 年初,mtl 和 transformers 是唯一被广泛使用的 monad 转换器库。