有没有人在野外遇到过莫纳德变形金刚?

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)中的任何标准.

  • 令我更加惊讶的是,显然,Norman Ramsey不知何故抽出时间在Stack Overflow上制作频繁,详细的答案,实际上也编写了非常重要的Haskell代码,同时也满足了他"日常工作"的任何要求......男人曾经睡过吗? (21认同)
  • @camcann:谢谢,我的网页上有一个.实际上,我被广泛认为是一个财团:http://spike.livejournal.com/468239.html?thread = 2204687#t2204687 (8认同)

snk*_*kid 8

monad变换器背后的概念非常棘手且难以理解,monad变换器导致非常复杂的类型签名

我觉得这有点夸张:

  • 使用变压器的特定Monad堆栈并不比普通的Monad更难使用.想想图层\叠加,你会没事的.您几乎总是不需要多次提升纯函数(或特定的IO操作).
  • 如上所述,已经将Monad堆栈隐藏在newtype中,使用generalized derive并隐藏模块中的数据构造函数.
  • 尽量不要在函数类型签名中使用特定的Monad堆栈,使用Monad类型类(如MonadIO,MonadReader和MonadState)编写通用代码(使用在Haskell 2010中标准化的灵活上下文扩展).
  • 使用像fclabels这样的库来减少访问Monad中记录部分的样板操作.

Monad变形金刚不是你唯一的选择,你可以写一个自定义Monad,使用延续Monad.您在IO(全局),ST(本地和受控,无IO操作),MVar(同步),TVar(事务性)中具有可变引用/数组.

我听说Monad变换器的潜在效率问题可以通过在mtl/transformers库的源中添加INLINE pragma来绑定/返回来减轻.