1

独自のメソッドで TraversableLike を拡張しようとしましたが、失敗しました。

まず、私が達成したいことを見てください:

class RichList[A](steps: List[A]) {
  def step(f: (A, A) => A): List[A] = {
    def loop(ret: List[A], steps: List[A]): List[A] = steps match {
      case _ :: Nil => ret.reverse.tail
      case _ => loop(f(steps.tail.head, steps.head) :: ret, steps.tail)
    }
    loop(List(steps.head), steps)
  }
}
implicit def listToRichList[A](l: List[A]) = new RichList(l)

val f = (n: Int) => n * (2*n - 1)
val fs = (1 to 10) map f
fs.toList step (_ - _)

このコードは正常に機能し、リスト要素間の違いを計算します。Seqしかし、Setだけでなく などでも動作するようなコードが必要Listです。

私はこれを試しました:

class RichT[A, CC[X] <: TraversableLike[X, CC[X]]](steps: CC[A]) {
  def step(f: (A, A) => A): CC[A] = {
    def loop(ret: CC[A], steps: CC[A]): CC[A] =
      if (steps.size > 1) loop(ret ++ f(steps.tail.head, steps.head), steps.tail)
      else ret.tail
    loop(CC(steps.head), steps)
  }
}
implicit def tToRichT[A, CC[X] <: TraversableLike[X, CC[X]]](t: CC[A]) = new RichT(t)

いくつかのエラーがあります。暗黙の変換でも++-method作業でもありません。また、新しいタイプの CC を作成する方法もわかりません。ループの呼び出しを参照してください。

4

1 に答える 1

2

Rex のコメントに基づいて、次のコードを作成しました。

class RichIter[A, C[A] <: Iterable[A]](ca: C[A]) {
  import scala.collection.generic.CanBuildFrom
  def step(f: (A, A) => A)(implicit cbfc: CanBuildFrom[C[A], A, C[A]]): C[A] = {
    val iter = ca.iterator
    val as = cbfc()

    if (iter.hasNext) {
      var olda = iter.next
      as += olda
      while (iter.hasNext) {
        val a = iter.next
        as += f(a, olda)
        olda = a
      }
    }
    as.result
  }
}
implicit def iterToRichIter[A, C[A] <: Iterable[A]](ca: C[A]) = new RichIter[A, C](ca)

val f = (n: Int) => n * (2*n - 1)
val fs = (1 to 10) map f
fs step (_ - _)

これは期待どおりに機能します。

于 2011-04-12T16:11:42.130 に答える