2009/3/13 Martijn van Steenbergen <mart...@van.steenbergen.nl>: > 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.
This reminds me of something similar I find a bit annoying: There are some functions like (<|>) which are defined separately in Text.Parsec and Control.Applicative, meaning that you have to hide one of the sets. Would it be better perhaps to just have Parsec reexport the existing functions from Applicative, or something like that? (Currently the functions in Parsec have the more specific type as Martijn says, but if they're generalised then I don't really see why they need to be duplicated.) _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe