Чтобы получить больше опыта работы со Scala и в качестве эксперимента, я реализую класс, который имеет List
-подобный API, но реализован как список IndexedSeq
с индексом для первого элемента; tail
просто возвращает копию с увеличенным индексом, а добавление Array
s равно O (1), а добавление Array
s равно O (m), m = длина списка ‹= количество элементов.
У меня проблемы с типами, возвращаемыми моей функцией. Практически каждый метод имеет параметры типа [R >: T : ClassManifest, A <: R : ClassManifest]
, где T
является параметром типа BlockList
. Иногда эти методы просто возвращают другие, но в этих ситуациях я получаю сообщение об ошибке от Eclipse, в котором говорится, что он искал тип BlockList[R]
, но нашел тип BlockList[Any]
. Разве R
не должен быть самым низким общим супертипом как для T
, так и для A
? В этом случае второй вызов метода также должен вернуть 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
}