编写我自己的通用地图功能

unk*_*946 5 generics collections scala

我正在尝试编写自己的泛型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
}
Run Code Online (Sandbox Code Playgroud)

这似乎适用于List,Vector但不适用于Maps.我应该做些什么改变,以便它也适用于Maps?

mis*_*tor 5

你的代码编译并运行得很好(注意:我使用的是Scala 2.9.0.1.你可能想提一下你正在使用的Scala版本.)

然而,map当你在Maps上应用时,你的函数总是返回一个List偶数,当它返回一个Map自己是有意义的.您可以通过更改CC[_]为避免这种情况CC.(相关博文:Scala中的Generic Quicksort.)

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
}
Run Code Online (Sandbox Code Playgroud)

但是你需要在调用它时显式地键入 - 注释这个函数,这有点让人伤心.

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)
Run Code Online (Sandbox Code Playgroud)

必须有一些方法来避免这种丑陋的类型注释,但我不知道它.


jil*_*len 3

以下代码对我有用。我认为你的“地图”功能与“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
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是列表(x,y)