here's the basic example.. I can't get scala to recognize that I want the ability to initialize my class in 2 different ways: via an existing sequence, or using multiple parameters.
The error I receive is:
double definition: method apply:(params: Int*)chorle.scala.tests.MultiParam and method apply:(pList:
Seq[Int])chorle.scala.tests.MultiParam at line 9 have same type after erasure: (params: Seq)chorle.scala.tests.MultiParam
Which ok, I get what's going on here - post compilation both functions result in the same header signature. However, in practice they do not work the same way - I can't envoke : apply(1,2,3) if I only have the apply(Seq) version... and I can't envoke apply(seq) the other way around. I am aware of various ways I could patch the actual function call, but how do I address this properly and only once in the class? Thank you!
class MultiParam protected (pList:Seq[Int])
object MultiParam {
def apply(pList:Seq[Int]): MultiParam = new MultiParam(pList)
def apply(params: Int *): MultiParam = new MultiParam(params)
}
The problem comes from the fact that the so-called "repeated params" form is syntactic sugar, both at the definition site and the invocation site for a special kind of IndexedSeq, which leads to the ambiguity.
There's a stock way to handle this, which you can find at various places in the standard collections library:
package rrs.scribble
object MP {
class MultiParam protected (pList:Seq[Int]) {
override def toString: String = pList.mkString("[[", ", ", "]]")
}
object MultiParam {
def apply(): MultiParam = new MP.MultiParam(List.empty[Int])
def apply(ints: Seq[Int]): MultiParam = new MP.MultiParam(ints)
def apply(i1: Int, iMore: Int*): MultiParam = new MP.MultiParam(i1 +: iMore)
}
}
In the REPL:
scala> MultiParam()
res0: rrs.scribble.MP.MultiParam = [[]]
scala> MultiParam(12)
res3: rrs.scribble.MP.MultiParam = [[12]]
scala> MultiParam(12, 34)
res4: rrs.scribble.MP.MultiParam = [[12, 34]]
scala> MultiParam(12, 34, 56)
res5: rrs.scribble.MP.MultiParam = [[12, 34, 56]]
Well, they can't be used as is because there's no way to generate both methods. The only way around it is to disambiguate them:
object MultiParam {
def apply(pList:Seq[Int]): MultiParam = new MultiParam(pList)
def apply(param: Int, params: Int *): MultiParam = new MultiParam(param +: params)
def apply(): MultiParam = new MultiParam(Nil)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With