I have a case class, taking a Seq[T] as parameter:
case class MyClass(value: Seq[T])
I now want to be able to write
MyClass(t1,t2,t3)
So I defined
object MyClass {
def apply(value: T*) = new MyClass(value.toSeq)
}
It doesn't work, because the case class defines
object MyClass {
def apply(value: Seq[T])
}
and Seq[T] and T* have the same type after erasure, so I can't overload them.
But I'd like to allow both access ways. Both ways should be allowed:
MyClass(t1,t2,t3)
MyClass(some_seq_of_T)
Since Seq[T] and T* are almost the same type (at least after erasure; and inside of the function having the parameter T* becomes Seq[T]), I think there should be a way to allow both ways of calling it.
Is there?
You could cheat a little bit and define your companion like this:
case class MyClass[T](value: Seq[T])
object MyClass {
def apply[T](first: T, theRest: T*) = new MyClass(first :: theRest.toList)
def apply[T]() = new MyClass[T](Nil)
}
The first apply handles the MyClass(1,2,3) as long as there is at least one argument.
The scond apply handles the 0-argument case. They don't conflict with the regular constructor.
This way you can write MyClass(Seq(1,2,3)), MyClass(1,2,3), and MyClass(). Just note that for the empty one you'll have to tell it what type to return, or else it will assume a MyClass[Nothing]
Here is solution without case classes:
scala> class A[T] (ts: Seq[T]) { def this(ts: T*)(implicit m: Manifest[T]) = this(ts) }
defined class A
scala> new A(1)
res0: A[Int] = A@2ce62a39
scala> new A(Seq(1))
res1: A[Seq[Int]] = A@68634baf
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