Alan Coromano
Alan Coromano

Reputation: 26038

Wrong number of arguments for pattern

There is a class with a very long list of the parameters for the constructor:

case class ClassA(a: Int, b: String, c: Int /*and so on*/)

I need to do a pattern matching against it:

val cls = getClassA
cls match {
  case ClassA(a, _, _, _, _, /* and so on */) => Some(a)
  case ClassA(_, _, c, _, _, /* and so on */) => Some(c)
  case _ => None
}

And I need to capture the value of a or c. Is it possible not to specify all the other parameters by _ if I really don't need them?

val cls = getClassA
    cls match {
      case ClassA(a, _*) => Some(a)
      case ClassA(_, _, c, _*) => Some(c)
      case _ => None
    }

It gave me the error: wrong number of arguments for pattern ClassA(a, b, /*and so on*/)

Upvotes: 3

Views: 1977

Answers (2)

Karol S
Karol S

Reputation: 9411

Since companion objects of case classes have unapply method, not unapplySeq, it doesn't work.

If you want to use unapply to check against only one field, you can define something like this:

object ClassAByA {
  def unapply(obj: ClassA) = Some(obj.a)
}

val ClassAByA(x) = ClassA(100, "thousand", 10000.0)
// x is equal 100 now

ClassA(100, "a", 10000.0) match {
  case ClassAByB(str) => str // str is equal "a" now
}

or you can just write:

something match {
  case c: ClassA => c.b
}

Upvotes: 4

yan
yan

Reputation: 20992

In case classes, you need to specify the entire list of parameters when matching.

An alternative would be to implement your own unapply method that correctly deals with whatever arguments you pass it.

Upvotes: 7

Related Questions