Haskell中的ApplicativeDo

5
据我所知,GHC8的新功能之一是ApplicativeDo语言扩展,它将do-notation尽可能地展开成相应的Applicative方法(<$><*>)。以下是我的问题。
它如何判断是否可以把do-notation展开成Applicative方法?据我所知,它会进行依赖性检查(如果后者依赖于前者的结果)来确定资格。还有其他标准吗?
尽管这种新增功能使得没有任何Monad实例的类的可读性更高,但对于既有Monad实例又有Applicative实例的结构:从可读性的角度来看,这是推荐的做法吗?是否还有其他好处?
1个回答

12
它是怎么决定是否可以将解糖到Applicative方法中的?据我所知,它进行依赖检查(如果后者依赖于前者的结果)以确定其资格。还有其他标准吗? 论文trac页面是最好的信息来源。一些要点:
- `ApplicativeDo` 尽可能使用 applicatives - 包括在某些情况下将其与 `>>=` 混合使用,其中仅部分 `do` 块是 applicative。 - 构建了一种依赖关系的有向图来查看哪些部分可以“并行化”。 - 有时这个图没有明显的最佳翻译!在这种情况下, GHC 选择大致上最小的本地翻译。
尽管这个补充使得没有任何Monad实例的类的应用程序代码更易于阅读(也许?)。但对于既有Monad又有Applicative实例的结构来说,从可读性的角度来看,这是一个推荐的做法吗?还有其他好处吗? 这里有一个关于ApplicativeMonad之间区别的答案。引用原话:
“使用<*>时,您选择两个计算,一个是函数,另一个是参数,然后它们的值通过应用程序进行组合。使用>>=时,您选择一个计算,并解释如何利用其产生的值选择下一个计算。这是“批处理模式”和“交互操作”的区别。”
一个典型的例子是Haxl单子(由Facebook设计),它专门用于从某个外部源获取数据。使用Applicative,这些请求可以并行发生,而Monad则强制这些请求按顺序执行。实际上,这个例子就是Simon Marlow在Facebook开发ApplicativeDo扩展以及撰写相关论文的原因。
通常情况下,大多数Monad实例并不一定能从Applicative中受益。引用同样的答案:
“我认为ApplicativeDo是一种非常好的方式,可以将以单子风格编写的程序转换为更加应用的(有时意味着更快)程序,而你没有时间进行重构。但除此之外,我会提倡‘尽可能使用Applicative,必要时使用Monad’这种方式来了解所发生的事情。”
所以:尽可能使用Applicative而不是Monad,并在实际需要时利用ApplicativeDo编写更好的代码(就像Facebook某些情况下必须这样做一样)。请注意保留HTML标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接