{-# OPTIONS -XTypeFamilies -XFlexibleContexts -XRankNTypes #-} -- | The parser type class. module ParserClass ( -- * The Parser type class Parser(..), ParserA, ParserM, -- * Some combinators symbol, token, choice, oneOf ) where import Control.Applicative import Control.Monad import Data.Traversable (sequenceA) import Data.Foldable (asum) -- | A parser consumes a list of symbols and produces a result on a valid parse. class (Functor p, Functor (ParseResult p)) => Parser p where -- | The type of the input symbols. type Input p :: * -- | The type constructor of the parse result. Typically allows failure, e.g. 'Maybe'. type ParseResult p :: * -> * -- | Recognise a symbol matching a predicate. satisfy :: (Input p -> Bool) -> p (Input p) -- | Runs the parser, producing a result. runParser :: p a -> [Input p] -> ParseResult p a -- | A polymorphic applicative parser. type ParserA s a = forall p. (Parser p, Alternative p, Input p ~ s) => p a -- | A polymorphic monadic parser. type ParserM s a = forall p. (Parser p, MonadPlus p, Input p ~ s) => p a -- | Recognise a specific symbol. symbol :: (Parser p, Eq (Input p)) => Input p -> p (Input p) symbol = satisfy . (==) -- | Recognise a specific string. token :: (Parser p, Eq (Input p), Applicative p) => [Input p] -> p [Input p] token = sequenceA . map symbol -- | Try all alternatives in order. (A synonym for 'asum'.) choice :: Alternative f => [f a] -> f a choice = asum -- | Recognise one of many symbols. oneOf :: (Parser p, Alternative p, Eq (Input p)) => [Input p] -> p (Input p) oneOf = choice . map symbol