Abstract types / type parameters in Scala

I am trying to write Scala code that should do something like:

class Test[Type] { def main { SomeFunc classOf[Type] val testVal: Type = new Type() } } 

and it does not work. I obviously don’t understand anything about Scala general options. It is clear that the misunderstanding is that in C ++ templates essentially function like string substitutions, so the new type () will work as long as the class passed to it has a default constructor. However, in Scala, types are different types of objects.

+16
types scala
May 4 '09 at 6:33
source share
1 answer

As you point out, C ++ has templates. In short, C ++ says that "there is a test for all T types so that Test compiles." This makes it easy to implicitly add constraints on T, but from the bottom, they are implicit and can be difficult for a user to understand your class without reading the code.

Scala parametric polymorphism (aka generics) works much more than ML, Haskell, Java, and C #. In Scala, when you write "class Test [T]", you say "for all T there is a type Test [T]" without restriction. It's easier to talk about formally, but that means you have to be frank about restrictions. For example, in Scala, you can say "class Test [T <: Foo]" to say that T must be a subtype of Foo.

C # has a way to add a constraint to T regarding constructors, but unfortunately Scala does not.

There are several ways to solve your problem in Scala. One of them is typical, but more detailed. The other is not typical.

A typical way looks like

 class Test[T](implicit val factory : () => T) { val testVal = factory } 

Then you can have many factories for types useful on your system.

 object Factories { implicit def listfact[X]() = List[X]() implicit def setfact[X]() = Set[X]() // etc } import Factories._ val t = new Test[Set[String]] 

If your library users need their own factories, they can add their own equivalent to the Factoryories object. One of the advantages of this solution is that you can use anything with a factory, whether or not the no-arg constructor exists or not.

The not-so-called method uses reflection and a function in Scala called manifestos, which are a way around the Java restriction regarding type erasure

  class Test[T](implicit m : Manifest[T]) { val testVal = m.erasure.newInstance().asInstanceOf[T] } 

In this version you are still writing

 class Foo val t = new Test[Foo] 

However, if there is no no-arg constructor, you get an exception at run time instead of a static type error

 scala> new Test[Set[String]] java.lang.InstantiationException: scala.collection.immutable.Set at java.lang.Class.newInstance0(Class.java:340) 
+28
May 04 '09 at 14:27
source share



All Articles