4

願わくば、これが図書館の売春斡旋に関する簡単な質問になることを願っています (このテーマに関する他の質問は、私の現在のスキル レベルを超える回答を生成する傾向があるためです)。

私がやりたいのは、コレクションとそれ自体の外積をマッピングすることだけです。

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 で提案されている方法を、次のような方法で試しました。

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, _)))
}

、しかし、それは私の(より単純に見える)方法と同じエラーをスローします。

ここで何が間違っていますか?

4

2 に答える 2

2

Scala 2.10 では、暗黙のクラスを直接使用できます (Miles の回答では、 IsTraversableLikeScala 2.10 も必要とするヘルパーを使用しています)。標準コレクションにはtoSelfCrossMappable(ひどい名前 BTW) は必要ないようです。以下は私にとってはうまくいきます:

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

implicit class CanCrossMap[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 }): That = 
      xs.flatMap { a => itl.conversion(xs.map(f(a, _)))
  } 
}

別のオプションは、IsTraversableLike完全に除外することです。

import collection.GenTraversableOnce

implicit class CanCrossMap[A, Repr](xs: GenTraversableLike[A, Repr]) {
  def crossMap[B, That <: GenTraversableOnce[B]](f: (A, A) => B)(
    implicit cbf: CanBuildFrom[Repr, B, That]): That = 
      xs.flatMap { a => xs.map(f(a, _))}
}

例:

Vector((1.0, 2.0), (3.0, 4.0), (5.0, 6.0)).crossMap { case ((ax, ay), (bx, by)) =>
  val dx = bx - ax
  val dy = by - ay
  math.sqrt(dx*dx + dy*dy)
}

Miles answer は、コレクションが直接 a ではないいくつかの追加のケース、GenTraversableLikeつまりArrayand (最後の例でforをString置き換えてみてください) をカバーしています。VectorArray

于 2013-05-06T17:51:31.300 に答える