Safe Haskell | Safe |
---|---|
Language | Haskell98 |
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 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
:: (Monad m, Stream s m z) | |
=> Indentation | Reference indentation |
-> ParsecT s u m () |
Parses only when indented past the level of the reference
:: (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
:: (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
:: (Monad m, Stream s m z) | |
=> Indentation | Reference indentation |
-> ParsecT s u m () |
Ensures the current indentation level matches that of the reference