私が持っているStream
データのを、私は最終以外の離れにすべてを投げたいn個の要素。入力に十分な要素がない場合、結果のストリームにはNone
。が埋め込まれます。これは私が思いついたものです:
def lastN[T](in: Stream[T], len: Int): Stream[Option[T]] =
in.foldLeft(Vector.fill[Option[T]](len)(None))(_.tail :+ Option(_)).to[Stream]
私が選んだVector
、その内部のバッファ用tail
およびappend
パフォーマンスの特性。
これはすべて正常に機能します。おそらくもっと良い方法がありますか?[注:常により良い方法があります。]
しかしIterator
、入力データのより適切な表現があると思いますか?問題ありません。の3つの言及をに置き換えるだけStream
でIterator
、すべて機能します。
さて、なぜどちらか/両方ではないのですか?
私はこのようなことができることを望んでいました:
import scala.language.higherKinds
def lastN[T, C[U] <: TraversableOnce[U] ](in: C[T], len: Int): C[Option[T]] =
in.foldLeft(Vector.fill[Option[T]](len)(None))(_.tail :+ Option(_)).to[C]
ああ、行かない。
エラー:Nothingタイプのコレクションに基づいて、Option [T]タイプの要素を使用してC [Option [T]]タイプのコレクションを作成できません。
私はCanBuildFrom
直接ファッツを試しましたが、魔法の公式を思い付いていません。
Queue
内部バッファとして使用する方が自然だと思います。これは、この種の処理により意味的に適してscala.collection.immutable.Queue
おり、2つList
ので実装され、実際にはより効率的である可能性がありVector
ます(もちろん、そうであるかどうかを確認するために測定を行う必要があります)。それ以外の場合、APIは完全に同じままです。言及Vector
をQueue
。に置き換えることができます。
に関してはCanBuildFrom
、to
メソッドを呼び出すためにコードで使用されます。完全な署名を参照して、何CanBuildFrom
を要求する必要があるかを確認できます。
def to[Col[_]](implicit cbf: CanBuildFrom[Nothing, A, Col[A]]): Col[A]
だから、あなたは必要になるでしょうCanBuildFrom[Nothing, Option[T], C[Option[T]]]
。
すべてをまとめると、可能な実装は次のようになります。
import scala.collection.generic.CanBuildFrom
import scala.collection.immutable.Queue
def lastN[T, C[U] <: TraversableOnce[U]](in: C[T], len: Int)(
implicit cbf: CanBuildFrom[Nothing, Option[T], C[Option[T]]]
): C[Option[T]] =
in.foldLeft(Queue.fill(len)(None: Option[T]))(_.tail :+ Option(_)).to[C]
あなたのコメントに関しては、コンパイラはそれを呼び出すto
ために必要CanBuildFrom[Nothing, Option[T], C[Option[T]]]
であることを知っていますが、抽象型を持つ暗黙の引数を自動的に見つけることはできません。
あなたが要求を入れた場合でもCanBuildFrom[Nothing, Option[T], C[Option[T]]]
にlastN
署名あなたは、たとえば呼び出したときに、その後lastN(Vector(1,2,3), 2)
、コンパイラはそれが知ってC
いるVector
、とT
あるInt
ので、それは通過しなければなりませんCanBuildFrom[Nothing, Option[Int], Vector[Option[Int]]]
。
ここでは、すべての型が具体的であり、コンパイラCanBuildFrom
は通常の暗黙的なルックアップルールを使用する関連インスタンスを見つけることができます。Vector
この例のコンパニオンオブジェクトで1つ見つかると思います。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加