eclipse
eclipse

Reputation: 3011

Scala erasure class type parameter

I have the following setup:

class Test[A](function: A => String) {
   def process(data: Any) {         //has to be Any since it is user IO
      if (data of Type A) 
          function(data)
   }
}

I cant seem to get the the typecheck to work. I tried adding an implicit TypeTag to Test[A] but I could not access it from within proccess. Is it possible to match against the type parameter of Test within the process function?

Upvotes: 1

Views: 112

Answers (3)

sjrd
sjrd

Reputation: 22085

Use a ClassTag and match for that purpose:

import scala.reflect.ClassTag

class Test[A : ClassTag](function: A => String) {
  def process(data: Any) { //has to be Any since it is user IO 
    data match {
      case data: A => function(data)
      case _       =>
    }
  }
}

Thanks to the implicit ClassTag in scope, the match can discriminate A even though it is generic.

Upvotes: 2

Ben Reich
Ben Reich

Reputation: 16324

I'm not sure why data has to be of type Any (wouldn't user input be of type String?), but if it truly does, then it probably reflects a situation where the type cannot be anticipated at compile time. In such a case, you probably want the method to throw a run-time error when trying to cast:

class Test[A](function: A => String) {
   def process(data: Any) = {
      function(data.asInstanceOf[A]) //might throw an error
   }
}

Or possibly use the Try monad:

class Test[A](function: A => String) {
   def process(data: Any) = {
      Try(function(data.asInstanceOf[A]))
   }
}

Of course what is most preferable would be to know the type of data at compile time:

class Test[A](function: A => String) {
   def process(data: A) = {
      function(data)
   }
}

Upvotes: 0

ponythewhite
ponythewhite

Reputation: 617

using Shapeless:

  class Test[A: Typeable](function: A => String){
    import shapeless.syntax.typeable._
    def process(data: Any) {         //has to be Any since it is user IO
      data.cast[A] map { function(_) }
    }
  }

This one is safe, in that it returns an Option[A], so when the cast fails, you can pattern match on the None.

Upvotes: 0

Related Questions