2014-09-21 81 views
1

我正在清理Genalgo中的序列類型,這是Scala的生物信息庫,但我遇到了一個問題。Scala中可擴展的自定義集合類型

在genalgo,有生物序列(DNA,RNA,蛋白質),所有這些都延伸了BioSequence特徵。現在,如果您在DNA/RNA /蛋白質上調用drop等方法,那麼您可以恢復您開始使用的類型。但是,如果您有一個類型參數設置爲BioSequence的方法,則在該類型的對象上調用方法(如drop)會返回IndexedSeq,但我希望它返回原始類型。作爲一種解決方法(https://github.com/shadaj/genalgo/commit/8c2756d214b4bcf1b8994c321c6587da7922b9fd),我已經優先於BioSequence中的drop來調用super方法並將結果轉換爲原始類型。即使使用此修復程序,只有drop已修復,但其他方法仍會返回IndexedSeq s。

下面是一個例子蒸餾水(和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 
    } 
} 

我如何能解決這個問題的任何想法?

+0

沒有足夠的信息,以便能夠回答的問題。不要鏈接到回購,並期望人們跟隨他們,嘗試包括提出問題所需的最低代碼。如果這意味着很多代碼,可能是代碼評論網站的問題。 – samthebest 2014-09-21 03:58:37

+0

@samthebest我不確定你的意思。底部的代碼塊('Example'對象)就是重現問題所需的全部內容。另外,我提供了一個小工具來讓測試代碼變得容易。 – shadaj 2014-09-21 07:47:06

回答

2

由於@samthebest評論沒有足夠的信息來完全回答這個問題,但也許這將幫助

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

視圖綁定的好用法! (恥辱他們被棄用,你可以重構使用上下文綁定?) – samthebest 2014-09-21 14:54:37

+0

謝謝。這給了我一個好去處的想法,在這種情況下,因爲不需要隱式轉換,所以它不需要像'def processSequence [B <:BaseLike,C <%BioSequence [B]和IndexedSeqLike [ B,C]](seq:C):C = seq.drop(1)' – shadaj 2014-09-21 18:44:37

+0

順便說一句,如果你對此感到好奇,那就是基於討論的提交。 https://github.com/shadaj/genalgo/commit/f7d5a22fae5b0d48dadee4e1fc0f31a3e17a0d77 – shadaj 2014-09-21 19:22:43