fickludd
fickludd

Reputation: 1157

Selecting a subset of types from a generic collection

Okay guys, I'm starting to get some scala now, but every now and then the trickier concepts get me. Let me introduce you to the fruit world:

class Fruit
class Pear extends Fruit
class Apple extends Fruit
class GrannySmith extends Apple

Now what if I want a new generic collection that allows me to pick subsets of Fruits out of the generic collection. Naive implementation:

class MyArray[T](var a:Array[T]) {
  def select[U <: T] = 
    a.filter(_ match {
      case u:U => true
      case _   => false
    })
}

This does not work however.

scala> var ma = new MyArray(
                        Array(
                          new Apple, 
                          new Fruit, 
                          new Pear, 
                          new GrannySmith, 
                          new Apple, 
                          new Fruit
                        ))


scala> ma.select[Apple]
res1: Array[Fruit] = Array(Apple@4d815146, Fruit@64fef26a, Pear@1ddd40f3, GrannySmith@28d320d6, Apple@3d10d68a, Fruit@1c751d58)

The console warned about unchecked errors, rerunning with -unchecked gave this while defining MyArray:

<console>:8: warning: abstract type U in type pattern U is unchecked since it is eliminated by erasure
             case u:U => true

So my understanding of type erasure is very vague. I know that it is somehow related to the limited dynamic types in the jvm, and that you can sometimes get around it using Manifests as Daniel is talking about here. What I particularly don't understand is how this works in this example, and how one could get around it.

I'm thankful for any help!

Upvotes: 2

Views: 244

Answers (1)

Jean-Philippe Pellet
Jean-Philippe Pellet

Reputation: 59994

How about this? You even get the right return type.

ma.a.collect { case a: Apple => a }

Upvotes: 3

Related Questions