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

时间:2017-10-07 05:17:49

标签: scala scala-streams

我正在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 functional design week3 video。有趣的是在上面的例子中,如果我删除第一个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}
    }
  } 

1 个答案:

答案 0 :(得分:2)

如果您只想创建Stream的泛型元素头,可以使用名为cons

的Stream包中的现有方法
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