如何在Scala中使用类型的类型成员?

时间:2016-03-08 18:20:45

标签: scala types

在Okasaki的“Purely Functional Data Structures”中,有一种情况我们创建一个类型字段的类,该类型是该类的类型参数的类型参数。 ML的来源是:

signature Queue
do
    type α Queue

    (* some methods *)
end

在Scala中,我使用Queue[E, 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
}

所以我们基本上有一个类型类来定义方位结构Q和元素E的操作。在我遇到CatenableList

之前,这对我来说很有效
functor CatenableListFromQueue(Q : Queue): CatenableList =
struct
    datatype α Cat = E | C of α × α Cat susp Q.Queue

    (* some methods *)
end 

现在datatype α Cat = E | C of α × α Cat susp Q.Queue似乎不适合Scala模型:它需要像

这样的东西
sealed trait Cat[+E, +Q[E, _]]

object Empty extends Cat[Nothing, Nothing]

case class C[E, Q](x: E, q: Q[Susp[Cat[E]], ???]) extends Cat[E, Q]

但是这需要类型构造函数Q[_, ???]可用;请注意,我们希望拥有元素类型,同时让调用者选择轴承结构。

在Haskell中,它看起来非常简单:

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

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

我想念什么?

1 个答案:

答案 0 :(得分:0)

显然,我应该采用Haskell方法:让CatList不知道队列细节,并请求一个类型类,它能够从我们提供的任何队列中提取所需类型的元素:

object CatenableListFromQueue {

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

  object Empty extends CatList[Nothing, Nothing]

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

class CatenableListFromQueue[E, Q](implicit q: Queue[CatList[Q, E], Q]) extends CatenableList[E] {

  type CL = CatList[Q, E]