在scala中进行遍历通用

时间:2014-05-22 22:57:26

标签: scala

我知道已经有一些在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​​}}

我如何实现我想要做的事情?

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)