title: Scala, pattern matching on a tuple of generic trait, checking if types are equal
body: <p>I know a lot of questions exist about type erasure and pattern matching on generic types, but I could not understand what should I do in my case from answers to those, and I could not explain it better in title.</p>
  
  <p>Following code pieces are simplified to present my case.</p>
  
  <p>So I have a trait</p>
  
  <pre><code> trait Feature[T] {
        value T
        def sub(other: Feature[T]): Double
   }
  
   // implicits for int,float,double etc to Feature with sub mapped to - function
   ...
  </code></pre>
  
  <p>Then I have a class</p>
  
  <pre><code> class Data(val features: IndexedSeq[Feature[_]]) {
       def sub(other: Data): IndexedSeq[Double] = {
           features.zip(other.features).map {
               case(e1: Feature[t], e2: Feature[y]) =&gt; e1 sub e2.asInstanceOf[Feature[t]]
           }
       }    
   }
  </code></pre>
  
  <p>And I have a test case like this</p>
  
  <pre><code>case class TestFeature(val value: String) extends Feature[String] {
       def sub(other: Feature[String]): Double = value.length - other.length
  }
  
  val testData1 = new Data(IndexedSeq(8, 8.3f, 8.232d, TestFeature("abcd"))
  val testData2 = new Data(IndexedSeq(10, 10.1f, 10.123d, TestFeature("efg"))
  
  testData1.sub(testData2).zipWithIndex.foreach { 
    case (res, 0) =&gt; res should be (8 - 10)
    case (res, 1) =&gt; res should be (8.3f - 10.1f)
    case (res, 2) =&gt; res should be (8.232d - 10.123d)
    case (res, 3) =&gt; res should be (1)
  }
  </code></pre>
  
  <p>This somehow works. If I try sub operation with instances of <code>Data</code> that have different types in same index of <code>features</code>, I get a <code>ClassCastException</code>. This actually satisfies my requirements, but if possible I would like to use <code>Option</code> instead of throwing an exception. How can I make following code work?</p>
  
  <pre><code> class Data(val features: IndexedSeq[Feature[_]]) {
       def sub(other: Data): IndexedSeq[Double] = {
           features.zip(other.features).map {
               // of course this does not work, just to give idea
               case(e1: Feature[t], e2: Feature[y]) if t == y =&gt; e1 sub e2.asInstanceOf[Feature[t]]
           }
       }    
   }
  </code></pre>
  
  <p>Also I am really inexperienced in Scala, so I would like to get feedback on this type of structure. Are there another ways to do this and which way would make most sense?</p>