01. ParsecT and Parsec monads
01. ParsecT and Parsec monads ๊ด๋ จ
ParsecT
is the main parser monad transformer and the central data type in megaparsec
. ParsecT e s m a
is parametrized like this:
e
is the type of custom component of error messages. If we do not want anything custom (and for now we do not), we just useVoid
from theData.Void
module.s
is the type of input stream.megaparsec
works out-of-the-box withString
, strict and lazyText
, and strict and lazyByteStrings
. It is also possible to work with custom input streams.m
is the inner monad of theParsecT
monad transformer.a
is the monadic value, result of parsing.
Since most of the time m
is nothing but Identity
, the Parsec
type synonym is quite useful:
type Parsec e s a = ParsecT e s Identity a
Parsec
is simply the non-transformer version of ParsecT
.
We can also draw an analogy between the monad transformers in megaparsec
and MTL monad transformers and classes. Indeed, there is also the MonadParsec
type class which is similar in its purpose to type classes such as MonadState
and MonadReader
. We will return to MonadParsec
later and discuss it in more details.
Speaking of type synonyms, the best way to start writing parser with megaparsec
is to define a custom type synonym for your parser. This is a good idea for two reasons:
It will be easier to add top level signatures like Parser Int
where Parser
is your parsing monad. Without the signatures, things like e
will often be ambiguousโit is the flip side of the polymorphic API of the library.
Working with concrete types with all type variables fixed helps GHC optimize a lot better. GHC cannot do much in terms of optimization if your parsers stay polymorphic. Although megaparsec
API is polymorphic, it is expected that end user will stick to a concrete type of parsing monad, so inlining and the fact that most functions have their definition dumped into so-called interface files will allow GHC produce very efficient non-polymorphic code.
Letโs define a type synonym (typically called Parser
) like this:
type Parser = Parsec Void Text
-- ^ ^
-- | |
-- Custom error component Type of input stream
Until we start dealing with custom parsing errors, when you see Parser in the chapter, assume this type.