Scala の経験を積むために、実験として、 のList
ような APIを持つクラスを実装しIndexedSeq
ていますが、最初の要素へのインデックスを持つ のリストとして実装されています。tail
インデックスがインクリメントされたコピーを返すだけで、先頭に追加する s はArray
O(1) ですが、追加するArray
s は O(m) です。m = リストの長さ <= 要素の数。
関数の戻り値の型に問題があります。ほぼすべてのメソッドには型パラメーターがあり[R >: T : ClassManifest, A <: R : ClassManifest]
、T
これは の型パラメーターですBlockList
。これらのメソッドが他のメソッドを返す場合もありますが、そのような状況では、Eclipse から type を探していたが typeBlockList[R]
が見つかったというエラーが表示されBlockList[Any]
ます。R
と の両方の最も一般的なスーパー タイプであってはT
なりA
ませんか? その場合、2 番目のメソッド呼び出しも を返す必要がありBlockList[R]
ますよね? 何が得られないのですか?型消去の問題を克服するためにいろいろ反省しClassManifest
ていますが、それでも問題があるかどうかはわかりません。
エラーは と の定義によるもの|:
です:|
。
import collection.immutable.List
import reflect.ClassManifest
import annotation.tailrec
sealed abstract
class BlockList [+T] extends Seq[T] with Product {
...
}
object EmptyBlock extends BlockList[Nothing] {
...
}
class Build [T: ClassManifest](
private val block: IndexedSeq[T],
private val next: BlockList[T] = EmptyBlock,
private val index: Int = 0
) extends BlockList[T] {
require(!block.isEmpty && index >= 0 && index < block.length)
override def |: [R >: T : ClassManifest, A <: R] (x: A): BlockList[R] =
Array[R](x) |: this //Return type error here
override def |: [R >: T : ClassManifest, A <: R : ClassManifest]
(blk: IndexedSeq[A]): BlockList[R] =
if (blk isEmpty) this
else new Build[R](blk, this)
override def :| [R >: T : ClassManifest, A <: R] (x: A): BlockList[R] =
this :| Array[R](x) //Return type error here
override def :| [R >: T : ClassManifest, A <: R : ClassManifest]
(blk: IndexedSeq[A]): BlockList[R] =
if (blk isEmpty) this
else new Build[R](block, next :| blk, index) //Type error here
}