Scala 工作表不适用于此代码,未显示编译错误

Scala worksheet not working for this code , no compilation error shown

我在 Eclipse 的 Scala 工作表中尝试了一些东西。这没有显示任何输出,也没有显示任何错误或警告。

object stream {
  println("Welcome to the Scala worksheet")

  def cons[T](hd: T, t1: => Stream[T]): Stream[T] = new Stream[T] {
    def head = hd
    private var t1Opt: Option[Stream[T]] = None
    def tail: Stream[T] = t1Opt match {
      case Some(x) => x
      case None => t1Opt = Some(t1); tail
    }
  }

  def streamIncrementedby2(x: Int): Stream[Int] = x #:: streamIncrementedby2(x + 2)

  val x = this.cons(-1, this.streamIncrementedby2(5))
  println(x.head)

}

我正在试用 courera odersky 课程中的示例:scala 功能设计第 3 周视频。有趣的是,在上面的例子中,如果我删除第一个 println 语句下面的所有内容,我会看到一个评估输出。

******* 更新 ******** 为了帮助其他读者,我发布了上述程序的更正版本,灵感来自答案。

 def cons[T](hd: T, t1: => Stream[T]) = new Stream[T] {
    override def head = hd
    override def isEmpty = false
    private[ this ] var t1Opt: Option[Stream[T]] = None
    def tailDefined: Boolean = true
    override def tail: Stream[T] = t1Opt match {
      case Some(x) => x
      case None => {t1Opt = Some(t1); tail}
    }
  } 

如果你只想制作一个 Stream 的通用元素头,你可以使用 Stream 包中的现有方法 cons

def streamIncrementedby2( x: Int ): Stream[ Int ] = x #:: streamIncrementedby2( x + 2 )

val x = Stream.cons( -1, this.streamIncrementedby2( 5 ) )
println( x.head )

它工作正常。但是,如果您想制作自己的版本,则必须深入挖掘。通过使用以下函数定义,您正在创建 构造函数 ,而不是普通函数

def cons[T](hd: T, t1: => Stream[T]): Stream[T] = new Stream[T] { ...

这里的关键是 = new Stream[T]。因此,你必须提供一个合适的构造函数需要的很多东西:覆盖抽象函数,如 headtailisEmpty,并提供必要的函数 tailDefined

def classCons[ T ]( hd: T, t1: => Stream[ T ] ): Stream[ T ] = new Stream[ T ] {

    override def isEmpty = false
    override def head = hd
    private[ this ] var tlVal: Stream[ T ] = _

    def tailDefined: Boolean = tlVal ne null

    override def tail: Stream[T] = {

        if ( !tailDefined )
            synchronized {
                if ( !tailDefined ) 
                    tlVal = t1
            }

        tlVal
    }
}

inspiration

您还可以使 cons 函数成为普通函数,并在不混淆构造函数的情况下获得相同的结果。

def funcCons[ T ]( hd: T, t1: => Stream[ T ] ): Stream[ T ] =  {

    if ( t1.isEmpty )
        Stream( hd )
    else 
        hd #:: t1.tail
}

结果相同:

val ccStream = classCons( -1, this.streamIncrementedby2( 5 ) )
val ffStream = funcCons( -1, this.streamIncrementedby2( 5 ) )
println( ccStream.head )
println( ffStream.head )
// Result => -1
// Result => -1