简体   繁体   中英

How to use type's type member in Scala?

In Okasaki's "Purely Functional Data Structures," there's a case when we create a class with a field of a type which is a type parameter of that class's type parameter. The source there is in ML:

signature Queue
do
    type α Queue

    (* some methods *)
end

In Scala, I model it with Queue[E, Q] , where E stands for α, and Q is the original Queue member type:

trait Queue[E, Q] {
  def empty: Q

  def isEmpty: Q => Boolean

  def snoc: (Q, E) => Q

  def head: Q => E

  def tail: Q => Q
}

So we essentially have a type class that defines operations for a bearing structure Q and elements E . That worked just fine for me for quite a while, until I encountered a CatenableList :

functor CatenableListFromQueue(Q : Queue): CatenableList =
struct
    datatype α Cat = E | C of α × α Cat susp Q.Queue

    (* some methods *)
end 

Now that datatype α Cat = E | C of α × α Cat susp Q.Queue datatype α Cat = E | C of α × α Cat susp Q.Queue doesn't seem to fit well into Scala model: it requires something like

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]

but that requires the type constructor Q[_, ???] to be available; note that we want to own the element type while leaving bearing structure to be chosen by the caller.

In Haskell, it looks very simple:

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

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

What do I miss?

Apparently, I should've taken the Haskell approach: make the CatList unaware of the queue details, and request a typeclass that's able to extract the elements of the desired type from whatever queue we're supplied with:

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]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM