2

Int から String を作成する Builder があります。

  class MyBuilder extends LazyBuilder[Int, String]
  {
    def result: String = "value: " + Int.toString
  }

そして、この CanBuildFrom 実装:

  class IntToStringCanBuildFrom extends CanBuildFrom[Set[Int], Int, String]
  {
    def apply(from: Set[Int]) = this.apply()
    def apply() : MyBuilder = new MyBuilder
  }

そして、次の例でそれを使用したいと思います。

val list = List(1, 2, 3)
val result = list.map(2*)(new IntToStringCanBuildFrom)

しかし、コンパイルエラーが発生します:

- type mismatch; found : Test.IntToStringCanBuildFrom required: 
 scala.collection.generic.CanBuildFrom[List[Int],Int,?]

ここで私は正確に何を間違っていますか?これを機能させる方法は?明らかに、私の CanBuildFrom 実装に String 型のパラメーターがあるという事実は好きではありませんが、これがこれを行う方法であるはずだと思いました。

4

1 に答える 1

3

これを行うには、コードをいくつか変更する必要があります。

  • まず、入力として機能するようCanBuildFromに定義されていますが、 (! ではありません) を指定します。したがって、たとえば、. aは であるため、動作します。Set[Int]List[Int]SetCanBuildFrom[Seq[Int], Int, String]ListSeq

  • 次に、怠惰なビルダーは、受け取った要素で実際に何かを行う必要があります。protected var parts: ListBuffer[TraversableOnce[Int]]追加されたすべてを含む を公開します。その内容を印刷しましょう:

    class MyBuilder extends LazyBuilder[Int, String] {
      def result: String = "value: " + parts.flatten.mkString(",")
    }
    

    次に、CanBuildFrom呼び出されたときにそのビルダーを作成できます。

    class IntSeqToStringCanBuildFrom extends CanBuildFrom[Seq[Int], Int, String] {
      def apply(from: Seq[Int]): Builder[Int, String] = apply()
      def apply(): Builder[Int, String] = new MyBuilder
    }
    
  • 最後に、直接使用できます。

    scala> val list = List(1, 2, 3)
    list: List[Int] = List(1, 2, 3)
    
    scala> val result = list.map(2 * _)(new IntSeqToStringCanBuildFrom)
    result: String = value: 2,4,6
    

    または暗黙のスコープを介して間接的に:

    scala> implicit val intSeqCanBuildFrom = new IntSeqToStringCanBuildFrom
    intSeqCanBuildFrom: IntSeqToStringCanBuildFrom = IntSeqToStringCanBuildFrom@52cc537d
    
    scala> val result: String = list.map(2 * _)
    result: String = value: 2,4,6
    
于 2013-07-27T14:07:03.163 に答える