{-# OPTIONS -XTypeFamilies -XFlexibleContexts -XRankNTypes #-} -- | The Satisfy type class. module Generics.Annotations.Satisfy ( -- * The Satisfy type class Satisfy(..), SatisfyA, SatisfyM, -- * 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 => Satisfy p where -- | The type of the input symbols. type Input p :: * -- | Recognise a symbol matching a predicate. satisfy :: (Input p -> Bool) -> p (Input p) -- | A polymorphic applicative parser. type SatisfyA s a = forall p. (Satisfy p, Alternative p, Input p ~ s) => p a -- | A polymorphic monadic parser. type SatisfyM s a = forall p. (Satisfy p, MonadPlus p, Input p ~ s) => p a -- | Recognise a specific symbol. symbol :: (Satisfy p, Eq (Input p)) => Input p -> p (Input p) symbol = satisfy . (==) -- | Recognise a specific string. token :: (Satisfy 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 :: (Satisfy p, Alternative p, Eq (Input p)) => [Input p] -> p (Input p) oneOf = choice . map symbol