希望这将是一个关于库拉皮条的简单问题(因为有关该主题的其他问题往往会产生超出我当前技能水平的答案)。

我要做的就是将一个集合的叉积与其自身映射。

val distances = points.crossMap(_ distance _)  // points: List[Point3d]


所以我尝试拉皮条Traversable这样:

implicit def toSelfCrossMappable[A](xs: Traversable[A]) = new {
  def crossMap[B](f: (A, A) => B) = xs.flatMap(a => xs.map(f(a, _)))
}


但这是行不通的(它没有进行隐式转换),我也不明白为什么不这样做(我对scala还是很陌生的)。我还尝试了Enriching Scala collections with a method中建议的方法,这给了我:

implicit def toSelfCrossMappable[A, C[A]](xs: C[A])(implicit c: C[A] => Traversable[A]) = new SelfCrossable[A, C[A]](xs)(c)

class SelfCrossable[A, C](xs: C)(implicit c: C => Traversable[A]) {
  def crossMap[B](f: (A, A) => B) = xs.flatMap(a => xs.map(f(a, _)))
}


,但会引发与我的方式(看起来更简单)相同的错误。

我在这里做错了什么?

最佳答案

这不是很漂亮,但这可以通过IsTraversableLike完成,

import scala.language.implicitConversions

import scala.collection.generic.{ CanBuildFrom, IsTraversableLike }
import scala.collection.GenTraversableLike

class SelfCrossMappable[A, Repr](xs: GenTraversableLike[A, Repr]) {
  def crossMap[B, That](f: (A, A) => B)
    (implicit
      cbf: CanBuildFrom[Repr, B, That],
      itl: IsTraversableLike[That] { type A = B }
    ) = xs.flatMap { a => itl.conversion(xs.map(f(a, _)))
  }
}

implicit def toSelfCrossMappable[Repr](xs: Repr)
  (implicit traversable: IsTraversableLike[Repr]) =
    new SelfCrossMappable(traversable.conversion(xs))


REPL会话示例,

scala> List("foo", "foo", "bar").crossMap(_ == _)
res0: List[Boolean] = List(true, true, false, true, true, false, false, false, true)

07-24 09:47
查看更多