Scala中延迟评估的正确使用

Scala中延迟评估的正确使用,scala,lazy-evaluation,sicp,Scala,Lazy Evaluation,Sicp,我试图重写《计算机程序的结构和解释》一书第3.5.4章中的以下示例: 以下是我的代码: def addStream(s1 : Stream[Double], s2 : Stream[Double]) : Stream[Double] = { (s1.head + s2.head) #:: addStream(s1.tail, s2.tail) } def scaleStream(stream : Stream[Double], factor : Double) : Stream[Doub

我试图重写《计算机程序的结构和解释》一书第3.5.4章中的以下示例:

以下是我的代码:

def addStream(s1 : Stream[Double], s2 : Stream[Double]) : Stream[Double] = {
  (s1.head + s2.head) #:: addStream(s1.tail, s2.tail)
}

def scaleStream(stream : Stream[Double], factor : Double) : Stream[Double] =    {
  (stream.head * factor) #:: scaleStream(stream.tail, factor)
}

def integral(integrandLazy: => Stream[Double], initialValue : Double, dt : Double) : Stream[Double] = {
  def int : Stream[Double] = {
    initialValue #:: addStream(scaleStream(evalStream, dt), int)
  }
  def evalStream : Stream[Double] ={
    lazy val stream : Stream[Double] = integrandLazy
    stream
  }
  int
}

def solve(f : Double => Double, y0 : Double, dt : Double) : Stream[Double] = {
  def y : Stream[Double] = {
    integral(dy, y0, dt)
  }
  def dy : Stream[Double] = {
    y.map(f)
  }
  y
}

val returnedStream = solve((x : Double) => {x}, 1, 0.001)
val limited = returnedStream take 30
limited foreach println
您可以看到,我试图使用Scala中的lazy val特性来模拟书中的延迟评估。程序运行,但当它尝试计算流中的第24个元素时,会被卡住


我的程序怎么了?我是否在Scala中使用了正确的功能来模拟延迟评估

在Scala中,
lazy val
s会在您提到它们时立即进行评估。所以在您的示例中,它没有完成任何事情,因为您在定义它之后就提到了它

本质上,您可以如下翻译
lazy val
(实际的翻译更复杂,因为它处理线程问题,但这里不介意):


从这次重写中,我们可以清楚地看到,整个过程基本上相当于急切地对
进行集成评估。

谢谢您的回复!我使用了你的代码,但这并不能解决问题。同样的行为仍然存在——它打印前24个数字(大约24个),然后程序挂起。我试图单步执行这个程序(这里使用IntelliJ),我确实看到了一些奇怪的递归。正如您还提到的线程问题——可能是这段代码调用的线程/递归问题的混合体?无论如何,我问题中的代码可以在对象扩展应用程序中轻松运行-请也尝试一下!)非常感谢你的帮助!
def evalStream: Stream[Double] = {
  var _stream: Stream[Double] = null
  var _streamInit: Boolean = false
  def stream: Stream[Double] = {
    if (!_streamInit) {
      _stream = integrandLazy
      _streamInit = true
    }
    _stream
  }
  stream
}