views:

303

answers:

2

Assume you have a List(1,"1") it is typed List[Any], which is of course correct and expected. Now if I map the list like this

scala> List(1, "1") map {
     |   case x: Int => x
     |   case y: String => y.toInt
     | }

the resulting type is List[Int] which is expected as well. My question is if there is an equivalent to map for filter because the following example will result in a List[Any]. Is this possible? I assume this could be solved at compile time and possibly not runtime?

scala> List(1, "1") filter {
     |   case x: Int => true
     |   case _ => false
     | }
+13  A: 

Scala 2.8:

scala> List(1, "1") partialMap {
     |   case x: Int => x
     | }
res0: List[Int] = List(1)
Daniel
+1  A: 

With regard to your modified question, if you simply use a guard in the case comprising your partialFunction, you get filtering:

scala> val l1 = List(1, 2, "three", 4, 5, true, 6)
l1: List[Any] = List(1, 2, three, 4, 5, true, 6)

scala> l1.partialMap { case i: Int if i % 2 == 0 => i }
res0: List[Int] = List(2, 4, 6)
Randall Schulz
Why is this only possible with a guard?
Joa Ebert
Sorry, that was a really stupid comment. But why is filter() not generating a result like partialMap?
Joa Ebert
@Joa `filter` does not change the type of a collection, because it does not modify its elements.
Daniel
Well, filter just takes a predicate, which gives the compiler nothing to go on for inferring the result type. Whereas with a partial function, it can use the types of the results of all the cases and compute an upper bound on those types as the overall type of the partial function.
Randall Schulz