The only differences between a Plain and a Lazy parser are the instance
of Applicative, and the type (and implementation) of runParser.
We therefore need to newtype the original Parser type, to allow it
to have a different instance.
A return type like Either, that distinguishes not only between
right and wrong answers, but also has commitment, so that a failure
cannot be undone. This should only be used for writing very primitive
parsers - really it is an internal detail of the library.
The z type is the remaining unconsumed input.
p onFail q means parse p, unless p fails, in which case
parse q instead.
Can be chained together to give multiple attempts to parse something.
(Note that q could itself be a failing parser, e.g. to change the error
message from that defined in p to something different.)
However, a severe failure in p cannot be ignored.
Push some tokens back onto the front of the input stream and reparse.
This is useful e.g. for recursively expanding macros. When the
user-parser recognises a macro use, it can lookup the macro
expansion from the parse state, lex it, and then stuff the
lexed expansion back down into the parser.
>>> some (putStr "la")lalalalalalalalala... * goes on forever *
Example1 expression
>>> some Nothingnothing
Example1 expression
>>> take 5 <$> some (Just 1)* hangs forever *
Note that this function can be used with Parsers based on
Applicatives. In that case some parser will attempt to
parse parser one or more times until it fails.
>>> many (putStr "la")lalalalalalalalala... * goes on forever *
Example1 expression
>>> many NothingJust []
Example1 expression
>>> take 5 <$> many (Just 1)* hangs forever *
Note that this function can be used with Parsers based on
Applicatives. In that case many parser will attempt to
parse parser zero or more times until it fails.
Instances36Alternative, …
AlternativeGetDefined in binary-0.8.9.3 · Data.Binary.Get.Internal
AlternativeSeqDefined in containers-0.7 · Data.Sequence.Internal
AlternativeSTMDefined in ghc-internal-9.1003.0 · GHC.Internal.Conc.Sync
sequence computations and combine their results (<*> and liftA2).
A minimal complete definition must include implementations of pure
and of either <*> or liftA2. If it defines both, then they must behave
the same as their default definitions:
Some functors support an implementation of liftA2 that is more
efficient than the default one. In particular, if fmap is an
expensive operation, it is likely better to use liftA2 than to
fmap over the structure and then use <*>.
This became a typeclass method in 4.10.0.0. Prior to that, it was
a function defined in terms of <*> and fmap.
Sequence actions, discarding the value of the first argument.
Examples
If used in conjunction with the Applicative instance for Maybe,
you can chain Maybe computations, with a possible "early return"
in case of Nothing.
Example1 expression
>>> Just 2 *> Just 3Just 3
Example1 expression
>>> Nothing *> Just 3Nothing
Of course a more interesting use case would be to have effectful
computations instead of just returning pure values.
Example4 expressions
>>> import Data.Char>>> import GHC.Internal.Text.ParserCombinators.ReadP>>> let p = string "my name is " *> munch1 isAlpha <* eof>>> readP_to_S p "my name is Simon"[("Simon","")]
Replace all locations in the input with the same value.
The default definition is fmap . const, but this may be
overridden with a more efficient version.
Examples
Perform a computation with Maybe and replace the result with a
constant value if it is Just:
Example2 expressions
>>> 'a' <$ Just 2Just 'a'>>> 'a' <$ NothingNothing
A variant of <*> with the types of the arguments reversed. It differs from
flip(<*>) in that the effects are resolved in the order the arguments are
presented.
Because we ignore the second type parameter to Const,
the Applicative instance, which has
(<*>) :: Monoid m => Const m (a -> b) -> Const m a -> Const m b
essentially turns into Monoid m => m -> m -> m, which is (<>)