实现自定义foreach以便更好地理解类型和功能组合

时间:2015-01-31 11:58:47

标签: scala

为了尝试理解我正在尝试的Scala类型系统 为List.foreach方法实现自定义实现:

package com

object customForEach extends App {

  class customForEach[B, A] extends Iterable[A] with collection.Seq[A] {

    def foreach[B](f: A ⇒ B) {
      var these = this
      while (!these.isEmpty) {
        f(these.head)
        these = these.tail
      }
    }

    def tail = this match {
      case h :: t ⇒ t

    }
  }
}

当我编译此代码时,我收到错误:

[error] \Desktop\Scala\src\main\scala\typeparam.scala:16: constructor cannot be instantiated to expected type;
[error]  found   : scala.collection.immutable.::[B(in class ::)]
[error]  required: com.customForEach.customForEach[B(in class customForEach),A]
[error]       case h :: t ? t
[error]              ^
[error] \Desktop\Scala\src\main\scala\typeparam.scala:16: not found: value t
[error]       case h :: t ? t
[error]                     ^
[error] \Desktop\Scala\src\main\scala\typeparam.scala:11: type mismatch;
[error]  found   : Seq[A]
[error]  required: com.customForEach.customForEach[B,A]
[error]         these = these.tail
[error]                       ^
[error] three errors found
[error] (compile:compile) Compilation failed
[error] Total time: 0 s, completed 31-Jan-2015 11:53:40

特别是我发现它以这种方式迭代了如何用List组合println:List(1,2,3).foreach(println)

我是否需要添加扩展另一个特征才能访问.tail函数?

对于此错误:

not found: value t
    [error]       case h :: t ? t

由于使用模式匹配运算符t创建了::,所以不应该找到{{1}}吗?

1 个答案:

答案 0 :(得分:2)

此代码无法正常工作的原因有很多。为了理解第一个编译器错误not found: value t,您必须在它之前查看错误。 ::仅适用于List,但此处您没有List,只有Iterable with Seq。该模式匹配无法正常工作,导致t变为"未找到"。

但是,还有更大的问题。即使您删除了tail的定义(这是不必要的),您也会发现您错过了applyiterator和{的抽象方法定义来自length特征的{1}}。我想你是这样做的,因为你无法延伸Seq,这是密封的。您可以从List复制applylength的实施,然后轻松实施LinearSeqOptimized方法,但还有另一个问题:您的课程没有有一个构造函数。

好的,我们再看看iterator再做些什么。 List是抽象的,有两个子类型List::Nil只是一个案例对象,Nil有一个构造函数,可以接受::的{​​{1}}和head。除非您还希望复制tailList的代码,否则这对您没有任何帮助。

Scala集合是非常大的复杂野兽,并且扩展它们以覆盖一个方法并不是一个简单的过程。