-
-
Notifications
You must be signed in to change notification settings - Fork 51
Open
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 Parser0However, 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).tupledIs 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) =>
...
}Metadata
Metadata
Assignees
Labels
No labels