我正在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}
}
}
答案 0 :(得分:2)
如果您只想创建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]
。因此,您必须提供正确构造函数所需的大量内容:覆盖head
,tail
和isEmpty
等抽象函数并提供必要的函数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