Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala - can unapply return varargs?

Object L1 below works. I can "create" an L1 by passing in varargs, which is nice, but I would like to be able to assign to an L1 using the same syntax. Unfortunately, the way I've done it here requires the uglier syntax of nesting an Array inside the L1.

object L1 {
    def apply(stuff: String*) = stuff.mkString(",")
    def unapply(s: String) = Some(s.split(","))
}
val x1 = L1("1", "2", "3")
val L1(Array(a, b, c)) = x1
println("a=%s, b=%s, c=%s".format(a,b,c))

I attempted accomplish this in what seems like an obvious way, as in L2 below:

object L2 {
    def apply(stuff: String*) = stuff.mkString(",")
    def unapply(s: String) = Some(s.split(","):_*)
}
val x2 = L2("4", "5", "6")
val L2(d,e,f) = x2
println("d=%s, e=%s, f=%s".format(d,e,f))

But this give the error:

error: no `: _*' annotation allowed here 
(such annotations are only allowed in arguments to *-parameters)`.

Is it possible for unapply to use varargs in this way?

like image 505
dhg Avatar asked Jun 28 '11 02:06

dhg


1 Answers

I think what you want is unapplySeq. Jesse Eichar has a nice write up on unapplySeq

scala> object L2 {
     |     def unapplySeq(s: String) : Option[List[String]] = Some(s.split(",").toList)
     |     def apply(stuff: String*) = stuff.mkString(",")
     | }
defined module L2

scala> val x2 = L2("4", "5", "6")
x2: String = 4,5,6

scala> val L2(d,e,f) = x2
d: String = 4
e: String = 5
f: String = 6
like image 79
jsuereth Avatar answered Sep 29 '22 15:09

jsuereth