Scala中的可扩展自定义集合类型

时间:2014-09-21 00:56:55

标签: scala scala-collections

我正在努力清理genalgo中的序列类型,这是Scala的生物信息库,但我遇到了一个问题。

在genalgo中,有生物序列(DNA,RNA,蛋白质)都延伸BioSequence性状。现在,如果你在DNA / RNA /蛋白质上调用像drop这样的方法,你会得到你开始使用的类型。但是,如果您的方法的类型参数设置为扩展BioSequence,则在该类型的对象上调用drop方法会返回IndexedSeq,但我希望它返回原始类型。作为一种解决方法(https://github.com/shadaj/genalgo/commit/8c2756d214b4bcf1b8994c321c6587da7922b9fd),我在drop中覆盖BioSequence来调用super方法并将结果转换为原始类型。即使使用此修复程序,只有drop已修复,但其他方法仍会返回IndexedSeq

以下是一个简化示例(如果您想在线试用,则为fiddle):

object Example {
  import scala.collection.IndexedSeqLike

  trait BaseLike

  class DNABase extends BaseLike

  trait BioSequence[B <: BaseLike] extends IndexedSeq[B]

  class DNA extends BioSequence[DNABase] with IndexedSeqLike[DNABase, DNA] {
    def length = 1
    def apply(idx: Int) = {
      new DNABase
    }
  }

  val myDNA = new DNA
  val droppedDNA: DNA = myDNA.drop(1) // Works because DNA extends IndexedSeqLike
  def processSequence[B <: BaseLike, C <: BioSequence[B]](seq: C): C = {
    seq.drop(1) // Doesn't work because BioSequence doesn't extend IndexedSeqLike
  }
}

关于如何解决此问题的任何想法?

1 个答案:

答案 0 :(得分:2)

正如@samthebest评论的那样,没有足够的信息来完全回答这个问题,但也许这会有所帮助

def processSequence[B <: BaseLike, C <% BioSequence[B] with IndexedSeqLike[B, C]](seq: C): C = 
  seq.drop(1)