| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Text.Pup.Class
Description
This module declares common high-level format-descriptor classes which are largely independent from the particular backend. Classes in this module are abstract over the type of token that you parse or print. Classes specialised to certain tokens can be found in Text.Pup.Class.Char.
The relevant class are re-exported by the modules which define backends. So unless you are defining a new backend, you shouldn't have to import this module.
Many docstrings in this module are adapted from Megparsec (see Text.Megaparsec) and Prettyprinter (see Prettyprinter).
Synopsis
- class (Eq tok, Eq chunk) => Tokens tok chunk (m :: Type -> Type -> Type -> Type) | m -> tok chunk where
- eof :: m r r ()
- single :: tok -> m r r tok
- satisfy :: (tok -> Bool) -> m (tok -> r) r tok
- tokens :: (chunk -> chunk -> Bool) -> chunk -> m (chunk -> r) r chunk
- takeWhileP :: Maybe String -> (tok -> Bool) -> m (chunk -> r) r chunk
- takeWhile1P :: Maybe String -> (tok -> Bool) -> m (chunk -> r) r chunk
- takeP :: Maybe String -> Int -> m (chunk -> r) r chunk
- label :: String -> m r r' a -> m r r' a
- hidden :: m r r' a -> m r r' a
- (<?>) :: Tokens chunk tok m => m r r' a -> String -> m r r' a
- chunk :: (Applicative m, Stacked m, Tokens tok chunk m) => chunk -> m r r ()
- anySingle :: Tokens tok chunk m => m (tok -> r) r tok
- anySingleBut :: Tokens tok chunk m => tok -> m (tok -> r) r tok
- oneOf :: (Foldable f, Tokens tok chunk m) => f tok -> m (tok -> r) r tok
- noneOf :: (Foldable f, Tokens tok chunk m) => f tok -> m (tok -> r) r tok
- takeRest :: Tokens tok chunk m => m (chunk -> r) r chunk
- atEnd :: (Alternative m, Tokens tok chunk m) => m r r Bool
- class Breaks (m :: k -> k -> Type -> Type) where
- class Breaks m => WadlerLeijen (m :: k -> k -> Type -> Type) where
- class LookAhead (m :: Type -> Type -> Type -> Type) where
- lookAhead :: m (a -> r) r a -> m (a -> r) r a
- notFollowedBy :: m r r a -> m r r ()
- class Annotations ann (m :: k -> k1 -> k2 -> Type) where
- annotate :: forall (r :: k) (r' :: k1) (a :: k2). ann -> m r r' a -> m r r' a
- class ParseErrors e (m :: Type -> Type -> Type -> Type) where
- parseError :: e -> m r r' a
- withRecovery :: (e -> m r r' a) -> m r r' a -> m r r' a
- observing :: m (b -> r) r a -> m (Either e b -> r) r (Either e a)
- newtype Trivial (m :: k -> k1 -> k2 -> Type) (r :: k) (r' :: k1) (a :: k2) = MkTrivial (m r r' a)
Basic token format descriptors
class (Eq tok, Eq chunk) => Tokens tok chunk (m :: Type -> Type -> Type -> Type) | m -> tok chunk where Source #
This class declares the basic format descriptors for tokens (what the theory of grammars call terminals).
Minimal complete definition
eof, single, satisfy, tokens, takeWhileP, takeWhile1P, takeP, label
Methods
As a parser, only succeeds at the end of input. No-op as a printer.
single :: tok -> m r r tok Source #
As a parser, only matches the single token single tt. As a
printer, prints the token single tt.
semicolon = single ';'
satisfy :: (tok -> Bool) -> m (tok -> r) r tok Source #
As a parser succeeds for any token for which the supplied
predicate pfsatisfy p returns True. As a printer satisfy p prints its input
token, provided predicate p@ returns True, and fails otherwise.
digitChar = satisfy isDigit <?> "digit" oneOf cs = satisfy (`elem` cs)
See also: anySingle, anySingleBut, oneOf, noneOf.
Arguments
| :: (chunk -> chunk -> Bool) | Predicate to check equality of chunks |
| -> chunk | Chunk of input to match against |
| -> m (chunk -> r) r chunk |
As a parser takes chunk tokens test chkchk' of input of length length
chk and returns chk' if the equality test test chk chk' succeeds, and
fails otherwise. As a printer, prints its input chunk
tokens test chkchk' provided that length chk' = length chk and the equality test test
chk chk' succeeds, and fails otherwise.
This can be used for example to write chunk:
chunk = tokens (==)
Arguments
| :: Maybe String | (Optional) name for a single token, can be used in error messages |
| -> (tok -> Bool) | Predicate to use to test tokens |
| -> m (chunk -> r) r chunk |
As a parser, parses zero or more tokens for which the supplied predicate holds. As a printer, prints its input chunk of tokens, provided that each token in the chunk satisfies the predicate.
This is an optimised variant of a format descriptor built with
many:
takeWhileP (Just "foo") f = many (satisfy f <?> "foo") takeWhileP Nothing f = many (satisfy f)
The parser side never fails, although it may parse the empty chunk.
Arguments
| :: Maybe String | (Optional) name for a single token, can be used in error messages |
| -> (tok -> Bool) | Predicate to use to test tokens |
| -> m (chunk -> r) r chunk |
Similar to takeWhileP, but fails if it can't parse or print at least one
token.
This is an optimised variant of a format descriptor built with
some:
takeWhile1P (Just "foo") f = some (satisfy f <?> "foo") takeWhile1P Nothing f = some (satisfy f)
Arguments
| :: Maybe String | Name for a single token in the row |
| -> Int | How many tokens to extract |
| -> m (chunk -> r) r chunk |
As a parser takeP lbl n returns the next n tokens from the input (it
fails if there are not enough tokens in the input). As a printer, it
prints its input chunk of tokens, provided that the chunk has exactly n
tokens.
label :: String -> m r r' a -> m r r' a Source #
gives a name to the next token expected by label lbl pp. This is
only really useful for the parser side, where it can be used to report
error messages of the form “unexpected ..., expected lbl”.
:: m r r' a -> m r r' a Source #
silences error messages of the form “unexpected ...,
expected ...” in hidden pp (only relevant on the parser side).
Instances
| Tokens Char Text (Backend ann) Source # | |
Defined in Text.Pup.Backend.Prettyprinter Methods eof :: Backend ann r r () Source # single :: Char -> Backend ann r r Char Source # satisfy :: (Char -> Bool) -> Backend ann (Char -> r) r Char Source # tokens :: (Text -> Text -> Bool) -> Text -> Backend ann (Text -> r) r Text Source # takeWhileP :: Maybe String -> (Char -> Bool) -> Backend ann (Text -> r) r Text Source # takeWhile1P :: Maybe String -> (Char -> Bool) -> Backend ann (Text -> r) r Text Source # takeP :: Maybe String -> Int -> Backend ann (Text -> r) r Text Source # label :: String -> Backend ann r r' a -> Backend ann r r' a Source # | |
| (MonadParsec err s m, tok ~ Token s, chunk ~ Tokens s, Eq tok, Eq chunk) => Tokens tok chunk (BackendGen m) Source # | |
Defined in Text.Pup.Backend.Megaparsec Methods eof :: BackendGen m r r () Source # single :: tok -> BackendGen m r r tok Source # satisfy :: (tok -> Bool) -> BackendGen m (tok -> r) r tok Source # tokens :: (chunk -> chunk -> Bool) -> chunk -> BackendGen m (chunk -> r) r chunk Source # takeWhileP :: Maybe String -> (tok -> Bool) -> BackendGen m (chunk -> r) r chunk Source # takeWhile1P :: Maybe String -> (tok -> Bool) -> BackendGen m (chunk -> r) r chunk Source # takeP :: Maybe String -> Int -> BackendGen m (chunk -> r) r chunk Source # label :: String -> BackendGen m r r' a -> BackendGen m r r' a Source # hidden :: BackendGen m r r' a -> BackendGen m r r' a Source # | |
| Ord err => Tokens Char Text (Pup err ann) Source # | |
Defined in Text.Pup.MPR Methods eof :: Pup err ann r r () Source # single :: Char -> Pup err ann r r Char Source # satisfy :: (Char -> Bool) -> Pup err ann (Char -> r) r Char Source # tokens :: (Text -> Text -> Bool) -> Text -> Pup err ann (Text -> r) r Text Source # takeWhileP :: Maybe String -> (Char -> Bool) -> Pup err ann (Text -> r) r Text Source # takeWhile1P :: Maybe String -> (Char -> Bool) -> Pup err ann (Text -> r) r Text Source # takeP :: Maybe String -> Int -> Pup err ann (Text -> r) r Text Source # label :: String -> Pup err ann r r' a -> Pup err ann r r' a Source # | |
| (Tokens tok chunk m1, Tokens tok chunk m2) => Tokens tok chunk (m1 :*: m2) Source # | |
Defined in Text.Pup.Class Methods eof :: (m1 :*: m2) r r () Source # single :: tok -> (m1 :*: m2) r r tok Source # satisfy :: (tok -> Bool) -> (m1 :*: m2) (tok -> r) r tok Source # tokens :: (chunk -> chunk -> Bool) -> chunk -> (m1 :*: m2) (chunk -> r) r chunk Source # takeWhileP :: Maybe String -> (tok -> Bool) -> (m1 :*: m2) (chunk -> r) r chunk Source # takeWhile1P :: Maybe String -> (tok -> Bool) -> (m1 :*: m2) (chunk -> r) r chunk Source # takeP :: Maybe String -> Int -> (m1 :*: m2) (chunk -> r) r chunk Source # label :: String -> (m1 :*: m2) r r' a -> (m1 :*: m2) r r' a Source # | |
(<?>) :: Tokens chunk tok m => m r r' a -> String -> m r r' a infix 0 Source #
A synonym for label in the form of an operator.
Arguments
| :: (Applicative m, Stacked m, Tokens tok chunk m) | |
| => chunk | Chunk to match |
| -> m r r () |
Arguments
| :: Tokens tok chunk m | |
| => tok | Token we should not match |
| -> m (tok -> r) r tok |
Arguments
| :: (Foldable f, Tokens tok chunk m) | |
| => f tok | Collection of taken we should not match |
| -> m (tok -> r) r tok |
As the dual of oneOf, succeeds and parses/prints the
current token if the current token isn't in noneOf tsts.
Note that, as a parser, can't automatically generate “expected”
tokens in error messages, so you should usually label it manually with
oneOf tslabel or (<?>).
noneOf cs = satisfy (`notElem` cs)
See also: satisfy.
atEnd :: (Alternative m, Tokens tok chunk m) => m r r Bool Source #
Return True when end of input has been reached.
atEnd = option False (True <$ hidden eof)
Breaks
class Breaks (m :: k -> k -> Type -> Type) where Source #
The typeclass implements format descriptors which represents
breaks. These are typically spaces and newlines. Because breaks can be many
spaces and/or newlines, the printer side must make decisions about how many
of which should be printed for a single break. Which is why these format
descriptors aren't merely derived from Breaks msatisfy.
Methods
space :: forall (r :: k). m r r () Source #
This parses 0 or more spaces/newline characters. As a printer a typical choice is to print no space at all.
space1 :: forall (r :: k). m r r () Source #
This parses 1 or more spaces/newline characters. As a printer a typical
choice is to print a soft newline (see also group).
hardline :: forall (r :: k). m r r () Source #
This parses/prints a newline character.
Instances
| (MonadParsec err s m, Token s ~ Char) => Breaks (BackendGen m :: Type -> Type -> Type -> Type) Source # | |
Defined in Text.Pup.Backend.Megaparsec Methods space :: BackendGen m r r () Source # space1 :: BackendGen m r r () Source # hardline :: BackendGen m r r () Source # | |
| Breaks (Backend ann :: Type -> Type -> Type -> Type) Source # | |
| Ord err => Breaks (Pup err ann :: Type -> Type -> Type -> Type) Source # | |
| Breaks m => Breaks (Trivial m :: k -> k -> Type -> Type) Source # | |
| (Breaks m1, Breaks m2) => Breaks (m1 :*: m2 :: k -> k -> Type -> Type) Source # | |
Wadler-Leijen-style grouping
class Breaks m => WadlerLeijen (m :: k -> k -> Type -> Type) where Source #
A class abstracting over the layout strategy of Wadler-Leijen-type pretty printers. All these format descriptors are no-ops on the parser side.
Methods
group :: forall (r :: k) (r' :: k) a. m r r' a -> m r r' a Source #
tries laying out group xx into a single line by interpreting the
contained line breaks (e.g. space1') as spaces; if this does not fit the
page, or when a hardline (see hardline) within x prevents it from being
flattened, x is laid out without any changes.
nest :: forall (r :: k) (r' :: k) a. Int -> m r r' a -> m r r' a Source #
lays out the document nest i xx with the current nesting level
(indentation of the following lines) increased by i. Negative values are
allowed, and decrease the nesting level accordingly.
>>>nest 4 ("lorem" <> space1 <> "ipsum" <> "dolor") <> line <> "sit" <> line "amet"lorem ipsum dolor sit amet
Instances
| (MonadParsec err s m, Token s ~ Char) => WadlerLeijen (BackendGen m :: Type -> Type -> Type -> Type) Source # | |
Defined in Text.Pup.Backend.Megaparsec Methods group :: BackendGen m r r' a -> BackendGen m r r' a Source # nest :: Int -> BackendGen m r r' a -> BackendGen m r r' a Source # | |
| WadlerLeijen (Backend ann :: Type -> Type -> Type -> Type) Source # | |
| Ord err => WadlerLeijen (Pup err ann :: Type -> Type -> Type -> Type) Source # | |
| Breaks m => WadlerLeijen (Trivial m :: k -> k -> Type -> Type) Source # | |
| (WadlerLeijen m1, WadlerLeijen m2) => WadlerLeijen (m1 :*: m2 :: k -> k -> Type -> Type) Source # | |
Look-ahead descriptors
class LookAhead (m :: Type -> Type -> Type -> Type) where Source #
This class declares look-ahead combinators. These allow parsers to react to the upcomming of the input without consuming it. They are ignored by printers.
Methods
lookAhead :: m (a -> r) r a -> m (a -> r) r a Source #
If p in succeeds (either consuming input or not) the
whole parser behaves like lookAhead pp succeeded without consuming anything (parser
state is not updated as well). If p fails fails without
consuming input.lookAhead p
notFollowedBy :: m r r a -> m r r () Source #
only succeeds when the parser notFollowedBy pp fails. This
parser never consumes any input and never modifies parser state. It
can be used to implement the “longest match” rule.
Instances
| MonadParsec err s m => LookAhead (BackendGen m) Source # | |
Defined in Text.Pup.Backend.Megaparsec Methods lookAhead :: BackendGen m (a -> r) r a -> BackendGen m (a -> r) r a Source # notFollowedBy :: BackendGen m r r a -> BackendGen m r r () Source # | |
| LookAhead (Backend ann) Source # | |
| Ord err => LookAhead (Pup err ann) Source # | |
| (Applicative m, Shifty m) => LookAhead (Trivial m) Source # | |
| (LookAhead m1, LookAhead m2) => LookAhead (m1 :*: m2) Source # | |
Semantic tagging
class Annotations ann (m :: k -> k1 -> k2 -> Type) where Source #
This class represents semantic tagging for printers. For instance,
instructions to add colour or font styles which may not be available in all
backends. A pup is `Annotate ann` when it supports tags of type ann'.
See also "Prettyprinter.annotate".
Instances
| Annotations ann (BackendGen m :: Type -> Type -> Type -> Type) Source # | |
Defined in Text.Pup.Backend.Megaparsec Methods annotate :: ann -> BackendGen m r r' a -> BackendGen m r r' a Source # | |
| Annotations ann (Backend ann :: Type -> Type -> Type -> Type) Source # | |
| Annotations ann (Pup err ann :: Type -> Type -> Type -> Type) Source # | |
| Annotations ann (Trivial m :: k1 -> k2 -> k3 -> Type) Source # | |
| (Annotations ann m1, Annotations ann m2) => Annotations ann (m1 :*: m2 :: k1 -> k2 -> k3 -> Type) Source # | |
Parse errors
class ParseErrors e (m :: Type -> Type -> Type -> Type) where Source #
A class for error handling in parsers.
Methods
parseError :: e -> m r r' a Source #
Stop parsing and report the e as a parsing error. No-op as a printer.
Arguments
| :: (e -> m r r' a) | How to recover from failure |
| -> m r r' a | Original parser |
| -> m r r' a | Parser that can recover from failures |
allows us to continue parsing even if the parser
withRecovery r pp fails. In this case r is called with the actual ParseError as
its argument. Typical usage is to return a value signifying failure to
parse this particular object and to consume some part of the input up
to the point where the next object starts.
Note that if r fails, the original error message is reported as if
without withRecovery. In no way recovering parser r can influence
error messages.
No-op as a printer.
allows us to "observe" failure of the observing pp parser,
should it happen, without actually ending parsing but instead getting
the ParseError in Left, and no input is consumed. On success parsed value is returned in
Right as usual.
As a printer is a no-op on observing pLeft and behaves like p on
Right.
Instances
| ParseErrors e' (Backend ann) Source # | |
| (ParseErrors e m1, ParseErrors e m2) => ParseErrors e (m1 :*: m2) Source # | |
| MonadParsec e s m => ParseErrors (ParseError s e) (BackendGen m) Source # | |
Defined in Text.Pup.Backend.Megaparsec Methods parseError :: ParseError s e -> BackendGen m r r' a Source # withRecovery :: (ParseError s e -> BackendGen m r r' a) -> BackendGen m r r' a -> BackendGen m r r' a Source # observing :: BackendGen m (b -> r) r a -> BackendGen m (Either (ParseError s e) b -> r) r (Either (ParseError s e) a) Source # | |
| Ord err => ParseErrors (ParseError Text err) (Pup err ann) Source # | |
Defined in Text.Pup.MPR Methods parseError :: ParseError Text err -> Pup err ann r r' a Source # withRecovery :: (ParseError Text err -> Pup err ann r r' a) -> Pup err ann r r' a -> Pup err ann r r' a Source # observing :: Pup err ann (b -> r) r a -> Pup err ann (Either (ParseError Text err) b -> r) r (Either (ParseError Text err) a) Source # | |
Deriving-via
newtype Trivial (m :: k -> k1 -> k2 -> Type) (r :: k) (r' :: k1) (a :: k2) Source #
A deriving-via constructor to derive instances for the classes in this module which can be implemented as no-ops.
Constructors
| MkTrivial (m r r' a) |
Instances
| Annotations ann (Trivial m :: k1 -> k2 -> k3 -> Type) Source # | |
| Breaks m => Breaks (Trivial m :: k -> k -> Type -> Type) Source # | |
| Breaks m => WadlerLeijen (Trivial m :: k -> k -> Type -> Type) Source # | |
| Applicative m => Applicative (Trivial m :: k -> k -> Type -> Type) Source # | |
Defined in Text.Pup.Class Methods pure :: forall a (i :: k). a -> Trivial m i i a # (<*>) :: forall (i :: k) (j :: k) a b (k1 :: k). Trivial m i j (a -> b) -> Trivial m j k1 a -> Trivial m i k1 b # liftA2 :: forall a b c (i :: k) (j :: k) (k1 :: k). (a -> b -> c) -> Trivial m i j a -> Trivial m j k1 b -> Trivial m i k1 c # (*>) :: forall (i :: k) (j :: k) a (k1 :: k) b. Trivial m i j a -> Trivial m j k1 b -> Trivial m i k1 b # (<*) :: forall (i :: k) (j :: k) a (k1 :: k) b. Trivial m i j a -> Trivial m j k1 b -> Trivial m i k1 a # | |
| Monad m => Monad (Trivial m :: k -> k -> Type -> Type) Source # | |
| (Applicative m, Shifty m) => LookAhead (Trivial m) Source # | |
| Shifty m => Shifty (Trivial m) Source # | |
Defined in Text.Pup.Class | |
| Stacked m => Stacked (Trivial m) Source # | |
Defined in Text.Pup.Class | |
| Applicative (m r r') => Applicative (Trivial m r r') Source # | |
Defined in Text.Pup.Class Methods pure :: a -> Trivial m r r' a # (<*>) :: Trivial m r r' (a -> b) -> Trivial m r r' a -> Trivial m r r' b # liftA2 :: (a -> b -> c) -> Trivial m r r' a -> Trivial m r r' b -> Trivial m r r' c # (*>) :: Trivial m r r' a -> Trivial m r r' b -> Trivial m r r' b # (<*) :: Trivial m r r' a -> Trivial m r r' b -> Trivial m r r' a # | |
| Functor (m r r') => Functor (Trivial m r r') Source # | |
| Monad (m r r') => Monad (Trivial m r r') Source # | |
| Additive (m r r' a) => Additive (Trivial m r r' a) Source # | |