Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can both unapply and unapplySeq be defined in the same extractor

Tags:

I have following code that aims to define unapply and unapplySeq in the same extractor

  test("pattern matching define unapply and unapplySeq") {
    object A {
      def unapply(arg: String): Option[(String, String)] = Some((arg, arg))

      def unapplySeq(arg: String): Option[Seq[String]] = Some(arg.split(" "))
    }

    def x = "hello world"

    x match {
      case A(a, b) => println("unapply matched", a, b)
      case A(a, b, _*) => println("unapplySeq matched", a, b)
    }


  }

But it seems not working,when I run this test case, it cause compiling error and complains that

Error:(292, 12) Star pattern must correspond with varargs or unapplySeq
      case A(a, b, _*) => println("unapplySeq matched", a, b)

I wonder whether it is possible to define both unapply and unapplySeq in the same extractor?

like image 722
Tom Avatar asked May 04 '18 00:05

Tom


1 Answers

According to this rather-dated-but-still-informative Scala blog entry:

Note: if both unapply and unapplySeq are defined only unapply is used.

And, indeed, tests appear to bear this out. One or the other works, but not both.


compiler errors explained

Due to the varargs notation (_*), the pattern A(a, b, _*) can only be recognized by unapplySeq(), but if you have both unapply() and unapplySeq() defined then only the unapply() is seen and the compiler is unable to make the pattern conform to the method definition.

If you comment out the unapply() definition, unapplySeq() will recognize, and parse, either of your case patterns (whichever one comes first since they both match).

like image 94
jwvh Avatar answered Nov 15 '22 04:11

jwvh