1

Given the following trait:

trait Foo[_ <: Product] {}

How can I pattern match on Foo's generic type?

In other words, is there a way to get at Foo's _ without using run-time reflection?

Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384
  • 1
    I doubt you could get that information even at runtime. Most probably that info is totally erased by that time. – Gábor Bakos Jan 09 '15 at 19:20
  • so, is my above code not `idiomatic`? Is there a common, idiomatic pattern for this approach? – Kevin Meredith Jan 09 '15 at 19:47
  • Well, it is not clear for me what you want to achieve. Maybe with `ClassTag`s or `Class` objects you can save the type information partially, but in that case I would not use existential type (`_`) as a type parameter, but a named one (`T` for example). – Gábor Bakos Jan 09 '15 at 19:56
  • 3
    possible duplicate of [Pattern matching on generic type in Scala](http://stackoverflow.com/questions/21285235/pattern-matching-on-generic-type-in-scala) – cmbaxter Jan 09 '15 at 20:13
  • Another related question: http://stackoverflow.com/questions/22388302/pattern-matching-on-listt-and-sett-in-scala-vs-haskell-effects-of-type-era?rq=1 – jhegedus Jan 10 '15 at 08:57
  • Yet another 5(!) year old related question : http://stackoverflow.com/questions/1094173/how-do-i-get-around-type-erasure-on-scala-or-why-cant-i-get-the-type-paramete – jhegedus Jan 10 '15 at 08:57

2 Answers2

1

The whole point of _ as a type parameter is to specify that the type is unknown.

Dima
  • 39,570
  • 6
  • 44
  • 70
  • I'm not sure this really qualifies as an answer. This seems more like a comment to me. Things like this might garner downvotes so you should consider switching it... – cmbaxter Jan 09 '15 at 20:32
  • Ok, the **answer** is "no, there is no way". Is that better? :) – Dima Jan 09 '15 at 20:45
  • Yes it is possible. See answer that I reluctantly posted (because it's a duplicate). – cmbaxter Jan 09 '15 at 21:00
  • 1
    @cmbaxter: your answer is about a different question. Try `val fooBar: Foo[_ <: Product] = new Foo[Bar]{}; checkType(foo)` – Dima Jan 09 '15 at 21:18
1

This is possible, and I still think it's a duplicate as noted by my comment, but wanted to show how you can do it anyway. Credit to om-nom-nom for the original answer:

  trait Foo[_ <: Product]

  case class Bar(i:Int)
  case class Baz(s:String)  

  val fooBar = new Foo[Bar]{}
  val fooBaz = new Foo[Baz]{}

  checkType(fooBar)
  checkType(fooBaz)

  def checkType[T <: Product : TypeTag](foo:Foo[T]){
    foo match{
      case f if typeOf[T] <:< typeOf[Bar] => println("its a bar")
      case f if typeOf[T] <:< typeOf[Baz] => println("its a baz")
    }
  }
cmbaxter
  • 35,283
  • 4
  • 86
  • 95