| Safe Haskell | Safe |
|---|---|
| Language | Haskell98 |
Text.Parsec.Indent.Explicit
Description
Introduction
The Indent module provides an implicit indentation parser.
For complex parsers split over many functions, this requires a good
understanding from the programmer which indentation is being referenced.
This module fixes that problem by explicitly passing around indentation as a first-class value. This commonly makes complex parsers less concise but easier to understand.
The problem with reference indentation
Many functions from that module (indented, checkIndent,
sameOrIndented...) use a reference indentation. This
reference indentation is stored in the IndentParserT type. It can be set
by calling withPos, but also by other functions such as block.
Consider the following code snippet:
import qualified Text.Parsec.Indent as I p = I.withPos $ do foo I.block $ I.checkIndent >> bar
I.checkIndent, in this case, will always succeed, since we are comparing
the current indentation to the implicit reference indentation set by
I.block, not by I.withPos, and there is no way to do the latter.
Explicit indentation
This module makes indentation first-class rather than implicit, so we can
provide a good implementation without relying on withPos:
import qualified Text.Parsec.Indent as I import qualified Text.Parsec.Indent.Explicit as EI p = do indentation <- EI.indentation foo I.block $ EI.checkIndent indentation >> bar
In order to preserve backwards-compatibility, the names in this module are chosen to match their counterparts in Text.Parsec.Indent.
Synopsis
- data Indentation
- indentation :: Monad m => ParsecT s u m Indentation
- indented :: (Monad m, Stream s m z) => Indentation -> ParsecT s u m ()
- sameOrIndented :: (Monad m, Stream s m z) => Indentation -> ParsecT s u m ()
- same :: (Monad m, Stream s m z) => Indentation -> ParsecT s u m ()
- block :: (Monad m, Stream s m z) => ParsecT s u m a -> ParsecT s u m [a]
- checkIndent :: (Monad m, Stream s m z) => Indentation -> ParsecT s u m ()
- topLevel :: (Monad m, Stream s m z) => ParsecT s u m ()
- notTopLevel :: (Monad m, Stream s m z) => ParsecT s u m ()
Indentation type
data Indentation Source #
We use our own position type that doesn't require a SourceName.
Instances
| Show Indentation Source # | |
Defined in Text.Parsec.Indent.Internal Methods showsPrec :: Int -> Indentation -> ShowS # show :: Indentation -> String # showList :: [Indentation] -> ShowS # | |
Obtaining a reference implementation
indentation :: Monad m => ParsecT s u m Indentation Source #
Obtain the current indentation, to be used as a reference later.
Indentation-based parser combinators
Arguments
| :: (Monad m, Stream s m z) | |
| => Indentation | Reference indentation |
| -> ParsecT s u m () |
Parses only when indented past the level of the reference
Arguments
| :: (Monad m, Stream s m z) | |
| => Indentation | Reference indentation |
| -> ParsecT s u m () |
Parses only when indented past the level of the reference or on the same line
Arguments
| :: (Monad m, Stream s m z) | |
| => Indentation | Reference indentation |
| -> ParsecT s u m () |
Parses only on the same line as the reference
block :: (Monad m, Stream s m z) => ParsecT s u m a -> ParsecT s u m [a] Source #
Parses a block of lines at the same indentation level starting at the current position
Arguments
| :: (Monad m, Stream s m z) | |
| => Indentation | Reference indentation |
| -> ParsecT s u m () |
Ensures the current indentation level matches that of the reference