Question

Reading through this informative, well-written article on Parser Combinators, I see this code:

class DisParser[+A](left: Parser[A], right: Parser[A]) extends Parser[A] {
  def apply(s: Stream[Character]) = left(s) match {
    case res: Success => res
    case _: Failure => right(s)
  }
}

When I try to compile this code, I get:

Parser.scala:19: error: class Success takes type parameters
    case res: Success => res
              ^
one error found

Given the signature of Parser:

case class Success[+A](value: A, rem: Stream[Character]) extends Result[A]

How can I change the case res: Success => res line to give Success a proper type parameter?

Was it helpful?

Solution

Which Success are you using? This one (Success from Parsers package) or this one (Success from util)? Both take type parameters, so you'll need to put it as

res @ Success(_, _) =>

otherwise you'll have to deal with the erasure warning.

OTHER TIPS

Your parser should return a value of type Result[A], as its type definition says (basically a parser is a function from character streams to a parse result).:

trait Parser[+A] extends (Stream[Character]=>Result[A])

So you have two options:

case res@Success(_,_) => res

Is a match against the variant of the returned case class.

case res:Success[_] => res.asInstanceOf[Success[A]]

Is a match against the returned type (using an instanceof operation). That's why you have to cast (you cannot match against a type parameter without a typetag value, since the JVM does type erasure).

Both are valid in your case, in the first case, you omitted the type parameter (that is what your original error was about). In your attempt to follow @wheaties advice, you made a syntax error somewhere in your code, but this is indeed the best way to go here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top