25

I have scala function that looks like this:

Now, depending upon the type of T (In my case, it can be Double, Boolean and LocalDate), I need to apply functions on ob. Something like this (I know the code will make no sense but I am trying to convey what I mean to do):

def X[T](ob: Observable[T]): Observable[T] = {
    //code  
    T match {
    case Double => DoSomething1(ob:Observable[Double]):Observable[Double]
    case Boolean => DoSomething2(ob:Observable[Boolean]):Observable[Boolean]
    case LocalDate => DoSomething3(ob:Observable[LocalDate]):Observable[LocalDate]
    }
}

Taking into consideration the Erasure property of Scala, can reflection be somehow used to get the job done? Is it even possible?

Core_Dumped
  • 4,577
  • 11
  • 47
  • 71
  • Where `t: T` (e.g. variable you're matching against) comes from? – om-nom-nom Jan 22 '14 at 14:14
  • @om-nom-nom I hope the edit makes it clear – Core_Dumped Jan 22 '14 at 14:17
  • 1
    Have you seen https://stackoverflow.com/questions/1094173/how-do-i-get-around-type-erasure-on-scala-or-why-cant-i-get-the-type-paramete ? – om-nom-nom Jan 22 '14 at 14:19
  • @om-nom-nom So, what do you suggest I do in my case? – Core_Dumped Jan 22 '14 at 14:29
  • 1
    This sounds more like something you could solve with inheritance and polymorphism. You can use regular overloading or subclassing. If nothing else look at cake pattern and finally magnet pattern. With magnet pattern you can pick your implementation flexibly. I don't know exactly what you are trying to do, so I can't give more concrete example. http://spray.io/blog/2012-12-13-the-magnet-pattern/ – yǝsʞǝla Jan 22 '14 at 15:58

1 Answers1

26

I would go with TypeTag if you're on 2.10+

import reflect.runtime.universe._

class Observable[Foo]

def X[T: TypeTag](ob: Observable[T]) = ob match {
    case x if typeOf[T] <:< typeOf[Double]   => println("Double obs")
    case x if typeOf[T] <:< typeOf[Boolean]  => println("Boolean obs")
    case x if typeOf[T] <:< typeOf[Int]      => println("Int obs")
}

X(new Observable[Int])
// Int obs

See also this lengthy, but awesome answer

Note also that I only took a glimpse at scala reflection, so likely somebody may write a better example of TypeTag usage.

Community
  • 1
  • 1
om-nom-nom
  • 62,329
  • 13
  • 183
  • 228
  • 2
    It should be noted that pattern matching on `ob` is redundant in this case, as it's all based on if-else logic and `x` doesn't change type. – Nikita Volkov Jan 22 '14 at 15:04
  • @NikitaVolkov yeah, I'm in a midway between simplified code and op's example where he used `ob` in `DoSomething(ob)`-like methods. – om-nom-nom Jan 22 '14 at 15:14
  • So there's no `compile-time` way to match on `T`'s type? In other words, this answer is *the* answer - there's no other way? – Kevin Meredith Jan 09 '15 at 21:06
  • @KevinMeredith I think so. There is a "Ways to Pattern Match Generic Types in Scala" blog post that provides more insight and alternatives: http://www.cakesolutions.net/teamblogs/ways-to-pattern-match-generic-types-in-scala – akauppi Jan 13 '17 at 19:11
  • Now "Ways to Pattern Match Generic Types in Scala" blog post can be found here: https://lepovirta.org/posts/2016-05-31-ways-to-pattern-match-generic-types-in-scala.html or https://gist.github.com/jkpl/5279ee05cca8cc1ec452fc26ace5b68b – Dmytro Mitin Jun 30 '19 at 03:36