2016-03-11 174 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]] 
} 

这样,这一切都编译得很好,似乎运作良好。