2011-07-23 8 views
5

Estoy tratando de escribir mi propia función genérica map y que sigue es lo que he llegado con:escribir mi propio mapa su funcionamiento genérico

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 
} 

Esto parece funcionar con List, Vector, pero no con la Map s. ¿Qué cambios debo hacer para que funcione con Map s también?

Respuesta

3

El siguiente código funciona para mí. Creo que su 'mapa' función solo funciona del mismo modo que 'Mapa # 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 
    } 
} 

salida es la lista (x, y)

5

Su código se compila y se ejecuta muy bien (Nota: estoy usando Scala 2.9.0.1. es posible que desee hablar de qué versión de Scala que está utilizando.)

Sin embargo, su función map cuando se aplica sobre Map s siempre devuelve un List incluso cuando tiene sentido para devolver un Map sí. Puede evitar eso cambiando CC[_] a CC.

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 
} 

Pero hay que escribir explícitamente-anotar esta función cuando se la invoca, que es un poco triste: (Relacionado blog A Generic Quicksort in Scala.).

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) 

Debe haber alguna forma de evitar esta fea anotación de tipo, pero no estoy al tanto.

Cuestiones relacionadas