I am trying to write my own generic map
function and following is what I have come up with:
def map[A, B, CC[X] <: Traversable[X], That]
(xs: CC[A])(f: A => B)
(implicit cbf: CanBuildFrom[CC[_], B, That]): That = {
val b = cbf(xs)
for (a <- xs)
b += f(a)
b.result
}
This seems to work with List
, Vector
, but not with the Map
s. What changes should I make so that it works with Map
s too?
Your code compiles and runs just fine (Note: I am using Scala 2.9.0.1. You might want to mention what version of Scala you are using.)
However your map
function when applied on Map
s always returns a List
even when it makes sense to return a Map
itself. You can avoid that by changing CC[_]
to CC
. (Related blog post: A Generic Quicksort in Scala.)
def map[A, B, CC <: Traversable[A], That]
(xs: CC)(f: A => B)
(implicit cbf: CanBuildFrom[CC, B, That]): That = {
val b = cbf(xs)
for (a <- xs)
b += f(a)
b.result
}
But you need to explicitly type-annotate this function when invoking it, which is a bit sad.
val xs = Map(45 -> 32, 11 -> 9)
map[(Int, Int), (Int, Int), Map[Int, Int], Map[Int, Int]](Map(45 -> 32, 11 -> 9))(identity)
// gives Map(45 -> 32, 11 -> 9)
There must be some way to avoid this ugly type annotation, but I am not aware of it.
Following code works for me. I think your 'map' function just work the same way as 'Map#map()'
object App {
def main(args: Array[String]) {
val map1 = Map(1 -> "x", 2 -> "y")
println(map1.map(_._2))
println(map(map1)(_._2))
}
def map[A, B, CC[X] <: Traversable[X], That](xs: CC[A])(f: A => B)(implicit cbf: CanBuildFrom[CC[_], B, That]): That = {
val b = cbf(xs)
for (a <- xs)
b += f(a)
b.result
}
}
output is List(x,y)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With