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.