Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 800
blintend Avatar asked Oct 02 '22 05:10

blintend


2 Answers

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

like image 144
som-snytt Avatar answered Oct 12 '22 12:10

som-snytt


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.

like image 39
wingedsubmariner Avatar answered Oct 12 '22 14:10

wingedsubmariner