We left off with a working solution for parsing either “po/k”, “x4/0”, and “s12” into our choice type of Operation. We can always go back and look at our original solution here. We really want to be able to parse a bunch of operations separated by a comma.
Parsing Many
When we want to parse a large blob of operations separated by a comma we can use the sepBy
function.
sepBy : Parser<‘a, ‘u> -> Parser<‘b, ‘u> -> Parser<‘a list, ‘u>
We can see by the function signature, it takes two parsers as arguments. The first parser determines the result. The second parser determines the separator. Our operations are separated by a comma so we’ll use pchar ‘,’
parser. Let’s combine the sepBy
with our previous function parseOperation
and can now parse an entire blob of operations.
"po/k,x4/0,s12,x7/6" |> run (sepBy parseOperation (pchar ','))
Alternative or Choice
Revisiting the parserOperation
function of
let parseOperation = pspin <|> pexchange <|> ppartner
we could have used the choice : seq> -> Parser<‘a,‘u>
function. choice
takes a collection of parsers and evaluates them in order to find a match. This can help with readability when having multiple alternative parsers. Instead of weaving the <|>
operator between them. We can re-write our function as:
let parseOperation = choice [ pspin; pexchange; ppartner ]
Summary
We’ve replaced our alternative operator <|>
with the choice
function for readability. We’ve also introduced the sepBy
function to parse a block of comma separated operations. The simplest way to test our parsers is by using the run
function as it does not require or use any state.