gpt4 book ai didi

scala - 如何用我自己的通用 `map`(正确的方法)丰富 Scala 集合?

转载 作者:行者123 更新时间:2023-12-01 11:54:28 25 4
gpt4 key购买 nike

我正在尝试用我自己的 map 来丰富 Scala 集合方法,我很接近,但隐式转换不起作用。除此之外,我还有什么想念的吗?我正在查看 Web 上的各种其他资源,包括这个问题被标记为重复的 SO 答案,许多地方在这里和那里遗漏了一些东西(例如使用 C[A] <: GenTraversable[A] ,使用 b()而不是 b(xs) ,忘记 Array ,忘记 BitSet 等等)。

implicit def conv[A,C](xs: C)(implicit ev: C <:< GenTraversableLike[A,C]) = new {
def mymap[B,D](f: A => B)(implicit b: CanBuildFrom[C,B,D]): D = b(xs).result // placeholder
}

scala> conv(List(1,2,3))
res39: java.lang.Object{def mymap[B,D](f: Int => B)(implicit b: scala.collection.generic.CanBuildFrom[List[Int],B,D]): D} = $$$$2c9d7a9074166de3bf8b66cf7c45a3ed$$$$anon$1@3ed0eea6

scala> conv(List(1,2,3))mymap(_+1)
res40: List[Int] = List()

scala> conv(BitSet(1,2,3))mymap(_+1)
res41: scala.collection.immutable.BitSet = BitSet()

scala> conv(BitSet(1,2,3))mymap(_.toFloat)
res42: scala.collection.immutable.Set[Float] = Set()

scala> List(1,2,3)mymap(_+1)
<console>:168: error: Cannot prove that List[Int] <:< scala.collection.IterableLike[A,List[Int]].
List(1,2,3)mymap(_+1)
^

scala> implicit def conv[A, C](xs: C)(implicit ev: C => GenTraversable[A]) = new {
| def mymap[B,D](f: A => B)(implicit b: CanBuildFrom[GenTraversable[A],B,D]): D =
| xs map f
| }
conv: [A, C](xs: C)(implicit ev: C => scala.collection.GenTraversable[A])java.lang.Object{def mymap[B,D](f: A => B)(implicit b: scala.collection.generic.CanBuildFrom[scala.collection.GenTraversable[A],B,D]): D}

scala> conv(Array(1)) mymap (_+1)
res6: scala.collection.GenTraversable[Int] = ArrayBuffer(2)

scala> Array(1) mymap (_+1)
<console>:68: error: No implicit view available from Array[Int] => scala.collection.GenTraversable[A].
Array(1) mymap (_+1)
^

最佳答案

我已经回答了this very question about type inference就在上周。这是代码:

implicit def conv[A,C <: GenTraversable[A]](xs: C with GenTraversableLike[A,C]) = new {
def mymap[B,D](f: A => B)(implicit b: CanBuildFrom[C,B,D]): D = {
val builder = b(xs)
xs foreach { x => builder += f(x) }
builder.result
}
}

我本可以使用 GenTraversable而不是 GenTraversableLike在这种特殊情况下。我更喜欢后者,因为它提供的更多。

问题是声明 [A, C <: GenTraversable[A]] 指示Scala推断A的类型来自 C 的类型.类型是根据它们在参数中的使用方式推断出来的,然后根据类型参数指定的边界进行检查。

所以当我写 xs: C with GenTraversable[A] ,我让 Scala 知道它应该推断出 A来自 xs .和写作GenTraversableLike[A, C]告诉 Scala 它应该选择一个返回 C 的集合对于返回相同集合的方法。这意味着您可以调用 filter得到 C回来,而不是得到 GenTraversable回来。

至于希望包含意见,我不知道你如何实现。

关于scala - 如何用我自己的通用 `map`(正确的方法)丰富 Scala 集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8472654/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com