0

我在 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 功能设计 week3 视频。有趣的是,在上面的例子中,如果我删除第一个 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}
    }
  } 
4

1 回答 1

2

如果您只想制作 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
    }
}

灵感

您还可以使您的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
于 2017-10-10T08:06:04.087 回答