答えて

7

あり、それを行う方法であり、それは次のように動作します、強化された方法は、要素型の両方を認識している上記の型シグネチャパターンを使用して

object enhance { 
    import scala.language.higherKinds 
    import scala.language.implicitConversions 
    import scala.collection.SeqLike 
    import scala.collection.generic.CanBuildFrom 

    implicit class Enhance[T, S[E] <: SeqLike[E, S[E]]](seq: S[T]) { 
    def first3(implicit cbf: CanBuildFrom[S[T], T, S[T]]) = seq.take(3) 
    def foo = seq.iterator 
    def goo(implicit cbf: CanBuildFrom[Nothing, T, S[T]]) = foo.take(3).to[S] 
    def moo[U](f: T => U)(implicit cbf: CanBuildFrom[S[T], U, S[U]]) = seq.map(f) 
    } 
} 

T(例えばIntまたはStringより上位の種類の配列型S(例:ListまたはVector)です。したがって、呼び出された配列型を正確に返すことができます。

多くのシーケンスメソッドは、暗黙のパラメータとしてEnhanceメソッドに追加されたCanBuildFromメソッドを必要とする可能性があります。ここでは、上記の例で必要です。続き

は、望ましい高kindedコレクションの戻り値の型を示す、サンプルの実行です:

scala> import enhance._ 
import enhance._ 

scala> (1 to 10).toList.first3 
res0: List[Int] = List(1, 2, 3) 

scala> (1 to 10).toVector.first3 
res1: Vector[Int] = Vector(1, 2, 3) 

scala> (1 to 10).toList.goo 
res2: List[Int] = List(1, 2, 3) 

scala> (1 to 10).toVector.goo 
res3: Vector[Int] = Vector(1, 2, 3) 

scala> (1 to 10).toList.moo(_.toDouble) 
res4: List[Double] = List(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) 

scala> (1 to 10).toVector.moo(_.toDouble) 
res5: Vector[Double] = Vector(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) 
+4

また、あなたが<[T、S [E]強化暗黙のクラス 'としてクラスを定義することができます。IterableLike [E、S 'asInstanceOf'は不要です。 –

+3

新しいメソッドで 'CanBuildFrom'をとる' map'や他のメソッドを使うと、うまくいきません。[E]]](seq:S [T]){'実装。結果はちょうど 'Seq'として出てくるでしょう。関連する暗黙の 'CanBuildFrom'を' Enhance'クラスまたはメソッドに渡す必要があります。 – Kolmar

+1

ありがとう@НиколайМитропольскийとKolmarの両方の変更は非常に便利です!私は元の答えを再現して、実際にそれらを示す。 – eje

関連する問題