Yes this:
chainl1 p op = foldl (flip ($)) <$> p <*> many (flip <$> op <*> p)
The idea is that you need to analyze p (op p)* and evaluate it as (...(((p) op p) op p)...) .
This may help expand the definition a bit:
chainl1 p op = foldl (\xf -> fx) <$> p <*> many ((\fy -> flip fy) <$> op <*> p)
When the op and p pairs are parsed, the results are applied immediately, but since p is the correct operand of op , it needs flip .
So, the result type of many (flip <$> op <*> p) is f [a -> a] . This list of functions is then applied from left to right on the initial value of p on foldl .
source share