{-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleContexts #-} module SavePos where import Control.Applicative import Control.Monad import Generics.MultiRec import Satisfy class SavePos p where -- type DataFam p :: * -> * -- | Signifies that the result of the parser is a member of the data type family and that its position information should be stored. savePos :: Ix (DataFam p) a => p a -> p a -- | A primitive for writing left-recursive grammars. @chainl p q@ recognises @p@, followed by zero or more @q@-@p@ combinations. @p@ is assumed to have already applied savePos on the resulting @a@. For any @q@-@p@ combination recognised in the input, 'savePos' is applied to the resulting @a@. chainl :: Ix (DataFam p) a => p a -> p (a -> a -> a) -> p a -- | A polymorphic applicative parser. type SatisfyA sym fam a = forall p. (Satisfy p, Alternative p, SavePos p, Input p ~ sym, DataFam p ~ fam) => p a -- | A polymorphic monadic parser. type SatisfyM sym fam a = forall p. (Satisfy p, Alternative p, MonadPlus p, SavePos p, Input p ~ sym, DataFam p ~ fam) => p a -- chainr1 :: Alternative f => f a -> f (a -> a -> a) -> f a -- chainr1 p op = scan where -- scan = flip id <$> p <*> rest -- rest = (flip <$> op <*> scan) <|> pure id