I am using Parsec to write a parser for a logfile. Every line of that logfile follows a common structure A:B:C:D
with the components A, B, C and D following simple rules. I've already written parsers for each of the components and I would like to combine them into a single parser. My current approach works, but I feel there has to be a nicer solution. One immediate drawback is that it would not scale very well for logfiles with more than 4 components.
parser :: (a -> b -> c -> d -> e) -> Parser a -> Parser b -> Parser c -> Parser d -> Parser e
parser f pa pb pc pd = f <$> pa <* (char ':') <*> pb <* (char ':') <*> pc <* (char ':') <*> pd
I searched for a fitting parser combinator, but the only combinator coming close is sepBy
, which does not work for this use case. Any help is appreciated!
CodePudding user response:
I think the best option is to introduce your own operator, e.g.:
infixl 4 <:>
p <:> q = p <* char ':' <*> q
Then you don't need to define a separate parse
function, it is just as easy to just write the implementation:
myParser = f <$> pa <:> pb <:> pc <:> pd
This is easily extended:
myParser2 = g <$> pa <:> pb <:> pc <:> pd <:> pe