Is it possible to express the chainl1 combinator from Parsec not using the Monad instance defined by parsec?
chainl1 p op =
do x <- p
rest x
where
rest x = do f <- op
y <- p
rest (f x y)
<|> return x
Yes, it is:
The idea is that you have to parse
p (op p)*and evaluate it as(...(((p) op p) op p)...).It might help to expand the definition a bit:
As the pairs of
opandpare parsed, the results are applied immediately, but becausepis the right operand ofop, it needs aflip.So, the result type of
many (flip <$> op <*> p)isf [a -> a]. This list of functions is then applied from left to right on an initial value ofpbyfoldl.