0

I wrote a code the other day to filter out mixing behavior form a list.

Her is an example code which should describe the problem I ran into.

def myFilter[A](toFilter : Any) : Option[A] = toFilter match {
  case keep : A => Some(keep)
  case _ => None
}

// what happens
myFilter[Int]("hallo") // => Option[Int] = Some(hallo)

// what I expect
myFilter[Int]("hallo") // => Option[Int] = None
myFilter[Int](1) // => Option[Int] = Some(1)

Maybe I'm doing something completely wrong, but it created a lot of problems on my side, I have to create a lot of code now, which I was hoping to make more readable by this function.

  • The exception will be thrown when you try to access the value, look at [this](http://stackoverflow.com/questions/26089390/why-asinstanceof-doesnt-throw-a-classcastexception/26089466#26089466) and [this](http://stackoverflow.com/questions/36138540/why-wrapping-a-generic-method-call-with-option-defers-classcastexception#comment59917366_36138540). – Ende Neu Apr 04 '16 at 15:10
  • That's nice, but sadly it does not solve my problem :( – user20998 Apr 04 '16 at 15:12

2 Answers2

1

Just provide a ClassTag:

scala> import scala.reflect.ClassTag
import scala.reflect.ClassTag

scala>   def myFilter[A: ClassTag](toFilter : Any) : Option[A] = toFilter match {
     |     case keep : A => Some(keep)
     |     case _ => None
     |   }
myFilter: [A](toFilter: Any)(implicit evidence$1: scala.reflect.ClassTag[A])Option[A]

scala> myFilter[Int]("hallo")
res2: Option[Int] = None

scala> myFilter[String]("hallo")
res3: Option[String] = Some(hallo)
Ende Neu
  • 15,581
  • 5
  • 57
  • 68
1

The type went away due Type Erasure. You can however provide the type, try something like

def myFilter[A](toFilter : Any)(implicit classTag: ClassTag[A]) : Option[A] = toFilter match {
  case keep : A => Some(keep)
  case _ => None
}
nob
  • 1,404
  • 10
  • 13