mar*_*ngw 52 monads haskell design-patterns monad-transformers
在我的业务领域 - 金融机构的后台IT - 软件组件通常进行全局配置,记录其进度,进行某种错误处理/计算短路是很常见的...可以通过Haskell中的Reader-,Writer-,Maybe-monads等很好地建模,并与monad变换器一起组合.
但似乎存在一些缺点:monad变换器背后的概念非常棘手且难以理解,monad变换器导致非常复杂的类型签名,并且它们会造成一些性能损失.
所以我想知道:monad变形金刚在处理上述常见任务时是最佳做法吗?
Nor*_*sey 43
Haskell社区在这个问题上存在分歧.
John Hughes报告说,他发现教monad变形金刚比教monad更容易,而且他的学生用"变形金刚第一"方法做得更好.
GHC开发人员通常会避免使用monad变换器,而是选择整合自己的monad,这些monad集成了他们需要的所有功能.(就在今天,我毫不含糊地告诉我GHC 不会使用我三天前定义的monad变压器.)
对我来说,monad变换器很像无点编程(即没有命名变量的编程),这是有意义的; 毕竟,它们在类型级别上完全是无点编程的.我从不喜欢无点编程,因为能够引入偶尔的名称是有用的.
我在实践中观察到的是
Hackage上可用的monad变换器的数量非常多,而且大多数都非常简单.这是一个典型的问题实例,学习大型库比滚动自己的实例更困难.
像作家,州和环境这样的Monads非常简单,我认为monad变换器并没有太大的好处.
monad变压器闪耀的是模块化和重用.Liang,Hudak和Jones在其标志性文章"Monad Transformers and Modular Interpreters"中精美地展示了这一属性.
在处理上述常见任务时,monad变压器是最佳实践吗?
我会说不. monad变换器是最佳实践的地方,你有一个相关抽象的产品线,你可以通过不同的方式组合和重用monad变换器来创建.在这样的情况下,你可能会开发一些对你的问题领域很重要的monad变换器(比如GHC拒绝的那个)你和(a)以多种方式组合它们; (b)为大多数变压器实现大量重复使用; (c)在每个monad变压器中封装一些非常重要的东西.
我被GHC拒绝的monad变压器不符合上述(a)/(b)/(c)中的任何标准.
monad变换器背后的概念非常棘手且难以理解,monad变换器导致非常复杂的类型签名
我觉得这有点夸张:
Monad变形金刚不是你唯一的选择,你可以写一个自定义Monad,使用延续Monad.您在IO(全局),ST(本地和受控,无IO操作),MVar(同步),TVar(事务性)中具有可变引用/数组.
我听说Monad变换器的潜在效率问题可以通过在mtl/transformers库的源中添加INLINE pragma来绑定/返回来减轻.