Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern matching on generic type in Scala

Tags:

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?

like image 466
Core_Dumped Avatar asked Jan 22 '14 14:01

Core_Dumped


People also ask

Does Scala have pattern matching?

Notes. Scala's pattern matching statement is most useful for matching on algebraic types expressed via case classes. Scala also allows the definition of patterns independently of case classes, using unapply methods in extractor objects.

What is case class and pattern matching in Scala?

It is defined in Scala's root class Any and therefore is available for all objects. The match method takes a number of cases as an argument. Each alternative takes a pattern and one or more expressions that will be performed if the pattern matches. A symbol => is used to separate the pattern from the expressions.

What are generics in Scala?

In Scala, forming a Generic Class is extremely analogous to the forming of generic classes in Java. The classes that takes a type just like a parameter are known to be Generic Classes in Scala. This classes takes a type like a parameter inside the square brackets i.e, [ ].

How do you write a match case in Scala?

Using if expressions in case statements First, another example of how to match ranges of numbers: i match { case a if 0 to 9 contains a => println("0-9 range: " + a) case b if 10 to 19 contains b => println("10-19 range: " + a) case c if 20 to 29 contains c => println("20-29 range: " + a) case _ => println("Hmmm...") }


1 Answers

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.

like image 98
om-nom-nom Avatar answered Feb 18 '23 04:02

om-nom-nom