
Hello, Looking at Parsec 3 I see:
chainr1 :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a chainr1 p op = scan where scan = do x <- p; rest x rest x = (do f <- op; y <- scan; return (f x y)) <|> return x
But if I remove the type signature and let GHC infer it for me, I get a much more generic type:
chainr1 :: (Alternative m, Monad m) => m a -> m (a -> a -> a) -> m a
But we don't really need m to be a monad since we're only doing applicative operations, so after some rewriting we get:
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
Would it be a good idea to: 1) make the Parsec combinators as generic as possible and 2) move the really generic applicative ones to Control.Applicative? Thanks, Martijn.