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.