Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a generic Scala function that returns an object based on the generic type?

(Scala beginner question)

I am trying to write a program in Scala that does a number of checks on C++ source files, and I want to implement optional logging of checks.

The following works fine for a single check:

  val headerFiles = files.filter(_.matches(".*?\\.h$"))
  val headerGuardChecker = if(options.contains('verbose)) {
    new HeaderGuard with LoggingFileCheckerTrait
  } else {
    new HeaderGuard
  } 
  headerFiles.foreach(h => if (! headerGuardChecker.check(new File(h))) println(h + " doesn't have a header guard"))

however when I try to generalize this using generics:

  def checker[T] = if(options.contains('verbose)) {
    new T with LoggingFileCheckerTrait
  } else {
    new T
  } 
  val headerFiles = files.filter(_.matches(".*?\\.h$"))
  headerFiles.foreach(h => if (! checker[HeaderGuard].check(new File(h))) println(h + " doesn't have a header guard"))

I get compile errors on the two new statements, claiming that T isn't a type. I believe this caused by type erasure, but I haven't found a way of working round this. Is there a way of doing what I want to do?

like image 311
Anthony Berent Avatar asked Dec 08 '11 13:12

Anthony Berent


People also ask

How do I return a generic type in Scala?

One way to do that in Scala is to define some factory that knows how to produce instances of our types and evidence that allows that factory to return our specific types. This is a version of the code above introducing such construct and using ContextBounds to obtain the right factory instance of the type we want.

How do I use generic in Scala?

To use a generic class, put the type in the square brackets in place of A . The instance stack can only take Ints. However, if the type argument had subtypes, those could be passed in: Scala 2.

How do you declare a generic method How do you invoke a generic method?

Generic MethodsAll generic method declarations have a type parameter section delimited by angle brackets (< and >) that precedes the method's return type ( < E > in the next example). Each type parameter section contains one or more type parameters separated by commas.


1 Answers

Take a look at Scala "manifests". They often allow you to circumvent type erasure on the JVM.

scala> def instantiate[T](implicit m:Manifest[T]) = m.erasure.newInstance().asInstanceOf[T]
instantiate: [T](implicit m: Manifest[T])T

scala> instantiate[String]
res0: String = ""

Here's a good intro for manifests in Scala

like image 52
Adam Rabung Avatar answered Oct 13 '22 15:10

Adam Rabung