Parsec:应用程序与Monads [英] Parsec: Applicatives vs Monads

查看:257
本文介绍了Parsec:应用程序与Monads的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始使用Parsec(在Haskell中几乎没有经验),我对使用monads或applicatives有点困惑。在阅读真实世界Haskell,写你一个Haskell之后,我总体的感觉是,应用程序是首选,但我真的不知道。



所以我的问题是:


  • 什么方法是首选?

  • monad和applicatives可以混合使用(当它们比另一个更有用时,使用它们)

  • 如果最后一个答案是肯定的,我应该怎么做?

$ b $一般来说,从对你最有意义的事情开始吧。然后考虑以下几点。



使用 Applicative (甚至是 Functor在可能的情况下)。像GHC这样的编译器通常更容易优化这些实例,因为它们可以比 Monad 更简单。我认为普通社区建议post- AMP 的作用是尽可能地将您的约束。我建议使用GHC扩展程序 ApplicativeDo do notation,而只有获得 Applicative 约束时因为 ParsecT 解析器类型是 Applicative 的一个实例。 code>和 Monad ,您可以将两者混合搭配。有些情况下,这样做更具可读性 - 这一切都取决于情况。

另外,请考虑使用 百万秒差距 megaparsec 是一种更为主动的维护方式,通常比较清晰,最近的分支是 parsec



编辑



两件事情,重读我的回答和评论,我确实没有很好地澄清:




  • 使用 Applicative 的主要好处是,对于许多类型,它允许更有效的实现(例如(*)) ap )。


  • 如果您只想写(+)< $> parseNumber< *> parseNumber ,没有必要放入 ApplicativeDo - 它会更加冗长。只有当您开始发现自己编写非常长或嵌套的应用表达式时,才会使用 ApplicativeDo

  • $ b

    I'm just starting with Parsec (having little experience in Haskell), and I'm a little confused about using monads or applicatives. The overall feel I had after reading "Real World Haskell", "Write You a Haskell" and a question here is that applicatives are preferred, but really I have no idea.

    So my questions are:

    • What approach is preferred?
    • Can monads and applicatives be mixed (use them when they are more useful than the other)
    • If the last answer is yes, should I do it?

    解决方案

    In general, start with whatever makes the most sense to you. Afterwards consider the following.

    It is good practice to use Applicative (or even Functor) when possible. It is in general easier for a compiler like GHC to optimize these instances since they can be simpler than Monad. I think the general community advice post-AMP has been to make as general as possible your constraints. I would recommend the use of the GHC extension ApplicativeDo since you can uniformly use do notation while only getting an Applicative constraint when that is all that is needed.

    Since the ParsecT parser type is an instance of both Applicative and Monad, you can mix and match the two. There are situations where doing this is more readable - this all depends on the situation.

    Also, consider using megaparsec. megaparsec is a more actively maintained just generally cleaner more recent fork of parsec.

    EDIT

    Two things that, rereading my answer and the comments, I really didn't do a good job of clarifying:

    • the main benefit of using Applicative is that for many types it admits much more efficient implementations (eg. (<*>) is more performant than ap).

    • If you just want to write something like (+) <$> parseNumber <*> parseNumber, there is no need to drop into ApplicativeDo - it would be just more verbose. I'd use ApplicativeDo only when you start finding yourself writing very long or nested applicative expressions.

    这篇关于Parsec:应用程序与Monads的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆