我知道已经有一些在scala中进行遍历通用的方法,但是我试图定义一个封装了一个可遍历类型的简单特征。但是,我无法获得类型签名。第一次尝试将类似于以下内容:
trait Traversable1[B] {
def head: Option[B]
def next: Traversable1[B]
}
这很有效,除了我希望next
返回一个与原始遍历类型相同的对象,而不是更通用的可遍历类型。例如,如果List
具有特征Traversable1
,则其next
方法应返回List
类型的内容,而不是Traversable1
。因此,我的第二次尝试如下:
trait Traversable2[A[B] <: Traversable2[A[B]] {
def head: Option[B]
def next: A[B]
}
此处A
可能等于List
,因此next
会返回List[B]
。不幸的是,此代码无法编译:{{1}}
我如何实现我想要做的事情?
答案 0 :(得分:3)
您可以创建一个特征:
trait Traversable[T[_]] {
def head[A](t: T[A]): Option[A]
def next[A](t: T[A]): T[A]
}
然后为以下列表实现它:
implicit val listTraversable = new Traversable[List] {
def head[A](l: List[A]) = l match {
case Nil => None
case x::_ => Some(x)
}
def next[A](l: List[A]) = l.tail
}
然后,您可以使用&#39;类型类&#39;来使用它。模式通过隐含的特征实现来完成工作,例如
def foreach[T[_], A](t: T[A], f: A => Unit)(implicit trav: Traversable[T]): Unit = {
trav.head(t) match {
case Some(v) =>
f(v)
foreach(trav.next(t), f)
case None => ()
}
}
并用
调用它foreach(List(1,2,3), println)