blintend
blintend

Reputation: 368

Zero-arg pattern matches when one arg expected

Given this definition in Scala:

class Foo(val n: Int)

object Foo {
  def unapply(foo: Foo): Option[Int] = Some(foo.n)
}

This expression compiles and returns ok:

new Foo(1) match {
  case Foo() => "ok"
}
  1. Why does this even compile? I would expect that an extractor with Option[T] implies matching patterns with exactly one argument only.
  2. What does the pattern Foo() mean here? Is it equivalent to Foo(_)?

In other words, what is the language rule that enables the experienced behavior.

Upvotes: 5

Views: 104

Answers (2)

som-snytt
som-snytt

Reputation: 39577

Today (in 2.11 milestone) you get the error:

<console>:15: error: wrong number of patterns for object Foo offering Int: expected 1, found 0
                case Foo() => "ok"
                     ^

I encountered this when adding Regex.unapply(c: Char). At some point, the case you point out was accepted, then later rejected. I remember I liked the idea that if my extractor returns Some(thing), then the Boolean match case r() would work the same as case r(_).

What works is in the scaladoc of unapply(Char) :

http://www.scala-lang.org/files/archive/nightly/docs-master/library/#scala.util.matching.Regex

Upvotes: 2

wingedsubmariner
wingedsubmariner

Reputation: 13667

Section 8.18 of the Scala Language Reference discusses this type of pattern matching. According to the reference, for a pattern like Foo(), it should only match if unapply returns a boolean. If unapply returns Option[T] for some T that isn't a tuple, then the pattern must include exactly one parameter, e.g. Foo(_). Unless I'm really misunderstanding what is happening here, it looks like this is an edge case where the compiler violates the spec.

Upvotes: 2

Related Questions