Roc obviously has a dearth of parser-combinator packages, so I wrote another one! :sweat_smile:
Started out writing this for another project, but ended up really liking the API and wanting to use it in some other projects, so I published it as it's own package, and thought I'd share.
import Parse exposing [char, integer, string, filter, rhs, lhs, both, zip_3, map, maybe, finalize]
dot = char |> filter(|c| c == '.')
expect
pattern = maybe(string("v")) |> rhs(integer) |> lhs(dot) |> both(integer) |> lhs(dot) |> both(integer)
parser = pattern |> map(|((major, minor), patch)| Ok({major, minor, patch}))
parser("v1.2.34") |> finalize == Ok({major: 1, minor: 2, patch: 34 })
expect
parser = rhs(maybe(string("v")), zip_3(integer, rhs(dot, integer), rhs(dot, integer)))
parser("v1.2.34_abc") |> finalize_lazy == Ok((1, 2, 34))
Gotta admit, I'm looking forward to static dispatch and doing this!
parser = string("v").rhs(integer).lhs(dot).both(integer).lhs(dot).both(integer)
What is lhs vs rhs vs both? I don't recognize those as common combinator names?
## keep the result of the left parser
lhs : Parser a _, Parser b _ -> Parser a _
lhs = |parser_l, parser_r|
zip(parser_l, parser_r) |> map(|(l, _r)| Ok(l))
## keep the result of the right parser
rhs : Parser a _, Parser b _ -> Parser b _
rhs = |parser_l, parser_r|
zip(parser_l, parser_r) |> map(|(_l, r)| Ok(r))
Our Rust parser code calls them skip_second
and skip_first
, not sure what the normal names are
I think skip_second
and skip_first
are pretty common names, also keep_left
and keep_right
. I was looking for really concise names to enable writing more complex grammars in a single line.
And both
is just an alias for zip
. Kinda silly since it’s actually longer than zip but I added that to be similar in flavor to lhs
/rhs
. :sweat_smile:
Sam Mohr said:
Our Rust parser code calls them
skip_second
andskip_first
, not sure what the normal names are
The normal names are obviously <*
and *>
:rolling_on_the_floor_laughing:
Truth be told, I was trying to get as close as I could to <*
, *>
, and <*>
as I could! :joy:
Last updated: Jul 06 2025 at 12:14 UTC