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:
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
.
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.