To create a new class that can be used in a Scala for comprehension, it seems that all you have to do is define a map function:
scala> class C[T](items: T*) {
| def map[U](f: (T) => U) = this.items.map(f)
| }
defined class C
scala> for (x <- new C(1 -> 2, 3 -> 4)) yield x
res0: Seq[(Int, Int)] = ArrayBuffer((1,2), (3,4))
But that only works for simple for loops where there is no pattern matching on the left hand side of <-
. If you try to pattern match there, you get a complaint that the filter
method is not defined:
scala> for ((k, v) <- new C(1 -> 2, 3 -> 4)) yield k -> v
<console>:7: error: value filter is not a member of C[(Int, Int)]
for ((k, v) <- new C(1 -> 2, 3 -> 4)) yield k -> v
Why is filter required to implement the pattern matching here? I would have thought Scala would just translate the above loop into the equivalent map
call:
scala> new C(1 -> 2, 3 -> 4).map{case (k, v) => k -> v}
res2: Seq[(Int, Int)] = ArrayBuffer((1,2), (3,4))
But that seems to work fine, so the for loop must be translated into something else. What is it translated into that needs the filter
method?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…