Написание своего собственного универсального функционала карты - PullRequest
5 голосов
/ 23 июля 2011

Я пытаюсь написать свою общую map функцию, и вот что я придумал:

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
}

Кажется, это работает с List, Vector, но не с Map s. Какие изменения я должен сделать, чтобы он работал и с Map s?

Ответы [ 2 ]

5 голосов
/ 23 июля 2011

Ваш код компилируется и работает просто отлично (Примечание: я использую Scala 2.9.0.1. Вы можете указать, какую версию Scala вы используете.)

Однако ваша функция map при применении к Map s всегда возвращает List, даже если имеет смысл возвращать Map. Вы можете избежать этого, изменив CC[_] на CC. (Связанное сообщение в блоге: Универсальная быстрая сортировка в 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
}

Но вам нужно явно вводить аннотации для этой функции при ее вызове, что немного печально.

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)

Должен быть какой-то способ избежать этой уродливой аннотации типа, но я не знаю об этом.

3 голосов
/ 23 июля 2011

Следующий код работает для меня.Я думаю, что ваша функция 'map' просто работает так же, как и '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
    }
}

. Вывод List (x, y)

...