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.
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to