Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing my own generic map functioni

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 Maps. What changes should I make so that it works with Maps too?

like image 342
unknown946 Avatar asked Jul 23 '11 04:07

unknown946


2 Answers

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 Maps 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.

like image 99
missingfaktor Avatar answered Oct 16 '22 11:10

missingfaktor


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)

like image 38
jilen Avatar answered Oct 16 '22 10:10

jilen