在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
我想念什么?
答案 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]