In the world of Scala Collections for every collection type there exists a companion object that helps make it easier to construct instances of the collection.
For simplicity consider this class and object of the same name:
object Numeric {
def apply(s: String): Numeric = new Numeric(s.toDouble)
}
case class Numeric(v: Double)
If you only had the case class then writing Numeric("5.1")
would be erroneous. With the object you can actually now call Numeric.apply("5.1")
or (because apply
is a special method) you can simply write Numeric("5.1")
. object
in Scala is analogous to holding all static
methods that you would write in Java.
Back to your example, MyType
is only the type alias to List[Int]
and does not bring the List
companion object into scope with the name MyType
. Your example is the equivalent of my Numeric
example without the companion object.
Thus, my answer, is to create a simple and generic way to construct your companion object that hides the fact that 1) MyType
is an alias and 2) that it restricts the collection type to Int
. If you have lots of type aliases like this one in your code then you'll probably want the more generic version here:
import scala.collection.GenTraversable
import scala.collection.generic.GenericCompanion
class TypeCompanion[CC[X] <: GenTraversable[X], T](companion: GenericCompanion[CC]) {
type InnerType = CC[T]
def apply(elems: T*): InnerType = companion.apply(elems: _*)
def empty(): InnerType = companion.empty[T]
}
object MyType extends TypeCompanion[List, Int](List)
type MyType = MyType.InnerType
If you want to reduce the number of times that you write List
, and will not mind the extra typing if you need to change from Int
to some other type, then you may prefer this variation:
class TypeCompanion[CC[X] <: GenTraversable[X]](companion: GenericCompanion[CC]) {
type InnerType = CC[Int]
def apply(elems: Int*): InnerType = companion.apply(elems: _*)
...
}
object MyType extends TypeCompanion(List)
type MyType = MyType.InnerType
Both implementations give your foo
method this implementation:
def foo(x: MyType): MyType = {
if (x.head == 0) MyType()
else if (x.head == -1) MyType(1,2,3,4)
else x
}
Note that the type restrictions on GenTraversable
and GenericCompanion
are just a clever way of restricting to companion objects that match scala collection's conventions.