typelevel / typelevel/cats-parse
Tuple semigroupal operations on parsers result in the wider Parser0 type - workarounds?
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 245
- Forks
- 51
- Avg merge
- 3h 20m
- Merged PRs (30d)
- 1
Description
The original design post contains this quite reasonable statement:
It is interesting to note how Parser1 composes with Parser: if you sequence one of each, you get a Parser1 as a result since once characters are consumed they are never unconsumed.
This is true when you use ~ to compose parsers:
val p1: Parser[A] = ...
val p2: Parser0[B] = ...
val combined1: Parser[(A, B)] = p1 ~ p2
val combined2: Parser[(B, A)] = p2.with1 ~ p1 // can use the with1 workaround if the left parser is Parser0
However, if you use the cats.syntax.contravariantSemigroupal operations to combine multiple parsers into a single tuple, to avoid working with nested tuples and for somewhat better syntax, this fails to work:
import cats.syntax.contravariantSemigroupal._
val p1: Parser[A] = ...
val p2: Parser0[B] = ...
// fails because p2 is Parser0, necessitating the use of Parser0 instances as they are "wider" in a sense,
// therefore `.tupled` returns `Parser0[(A, B)]`
val combined1: Parser[(A, B)] = (p1, p2).tupled
Is there a workaround for this, except using ~? The thing is, multiple ~s in a row result in the parser value being a lot of nested tuples, which doesn't look very nice:
(a ~ b ~ c ~ d ~ e).map {
case ((((x1, x2), x3), x4), x5) =>
...
}
// vs tupled/mapN, if it was possible:
(a, b, c, d, e).mapN {
(x1, x2, x3, x4, x5) =>
...
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with Parser, Parser0, and cats.syntax.contravariantSemigroupal, focusing on tupled and mapN for mixed Parser and Parser0 values. Trace the relevant composition and type-inference behavior, then determine whether tuple composition can retain Parser; done should be a clear workaround or a resolved API behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100