2016-03-11 169 views
0

場類型,以便於Recursive type definition in Scala跟進,現在我有我的類型的CatenableListFromQueue數據承載結構:使用類型參數的類型參數作爲斯卡拉

object CatenableListFromQueue { 

    sealed trait CatList[+Q, +E] 

    object Empty extends CatList[Nothing, Nothing] 

    case class C[Q[_], E](x: E, q: Q[CatList[Q, E]]) extends CatList[Q, E] 
} 

現在的參數Q是預期值,自然就是一個隊列。我Queue本身是一種類,即它僅僅定義了一些通用的數據承載結構的方法:

trait Queue[E, Q] { 

    def empty: Q 

    def isEmpty: Q => Boolean 

    def snoc: (Q, E) => Q 

    def head: Q => E 

    def tail: Q => Q 
} 

這似乎只是正常工作對我來說,例如

class BatchedQueue[E] extends Queue[E, (List[E], List[E])] { 
    override def empty: (List[E], List[E]) = (Nil, Nil) 

    override def isEmpty: ((List[E], List[E])) => Boolean = { 
    case (Nil, _) => true 
    case _ => false 
    } 

    val checkf: (List[E], List[E]) => (List[E], List[E]) = { 
    case (Nil, r) => (r.reverse, Nil) 
    case q => q 
    } 

    override def snoc: ((List[E], List[E]), E) => (List[E], List[E]) = { 
    case ((f, r), x) => checkf(f, x :: r) 
    } 

    override def tail: ((List[E], List[E])) => (List[E], List[E]) = { 
    case (Nil, _) => throw new IllegalStateException("tail called on an empty queue") 
    case ((_ :: f), r) => checkf(f, r) 
    } 

    override def head: ((List[E], List[E])) => E = { 
    case (Nil, _) => throw new IllegalStateException("head called on an empty queue") 
    case ((x :: _), _) => x 
    } 
} 

這一切都進行得很順利,直到我需要創建一個CatenableListFromQueue,從前面的問題持有的數據結構與Queue的數據承載結構,Queue#Q

class CatenableListFromQueue[E, CL, Q](queue: Queue[E, Q]) extends CatenableList[E] { 

    type CL = CatList[queue#Q, E] 

所以在我的理想世界該類獲得Queue的一個實例,即在一些結構(這裏:Queue#Q)上實現隊列操作,並反過來創建並處理CatList的實際元素和Queue#Q的包含ning進一步CatList s。

問題是,我似乎無法想出一種在Scala中編寫代碼的方法;在Haskell,似乎微不足道:

data CatList q a = E | C a (q (CatList q a)) 

instance Queue q => CatenableList (CatList q) where 
    -- methods 

但在斯卡拉我不能想出什麼辦法來編碼相同作爲我Queue要求數據承載結構作爲參數,數據承載含有天然它在這種情況下包含相同類型的其他數據承載結構。

回答

0

那麼接下來Haskell的做法是正確的做法:

object CatenableListFromQueue { 

    sealed trait CatList[+Q[_], +E] 

    object Empty extends CatList[Nothing, Nothing] 

    case class C[Q[_], E](x: E, q: Q[Susp[CatList[Q, E]]]) extends CatList[Q, E] 
} 

trait CatenableListFromQueue[E, QBS[_]] extends CatenableList[E, CatList[QBS, E]] { 

    type Q = Queue[Susp[CatList[QBS, E]], QBS[Susp[CatList[QBS, E]]]] 

    def q: Q 

    type CL = CatList[QBS, E] 

    def just(e: E): CL = C(e, q.empty) 

    // etc. 

所以我們保持CatenableListFromQueue一個特點,後來與一個特定的類型QBS使用它:

new CatenableListFromQueue[Int, HoodMelvilleQueue.Repr] { 
    val q = new HoodMelvilleQueue[Susp[CL]] 
} 

這樣,這一切都編譯得很好,似乎運作良好。