scala中的函数编程 - 无限流

zha*_*uan 6 functional-programming scala

我正在完成本书的练习和概念:Scala中的函数编程.假设我需要定义一个constant函数,该函数按给定值返回无限流.

这是我的版本:

def constant[A](a: A): Stream[A] = Stream.cons(a, constant(a))
Run Code Online (Sandbox Code Playgroud)

GitHub中的答案:

def constant[A](a: A): Stream[A] = {
  lazy val tail: Stream[A] = Cons(() => a, () => tail)
  tail
}
Run Code Online (Sandbox Code Playgroud)

评论说后者比前者更有效,因为它只是一个引用自身的对象.我无法理解这一点,任何帮助都将不胜感激.(抱歉我的英语不好:)

HTN*_*TNW 8

假设您定义constant第一种方式.现在,

constant(something)
Run Code Online (Sandbox Code Playgroud)

这是一个Cons单元格,它引用了惰性值somethingconstant(something)

Cons(() => something, () => constant(something))
Run Code Online (Sandbox Code Playgroud)

现在,让我们尝试获得第1000个元素.我们需要评估尾部,因为我们需要比第一个元素更深入.所以,我们执行constant(something),然后我们得到一个看起来像原始的 Cons单元格:

Cons(() => something, () => constant(something))
Run Code Online (Sandbox Code Playgroud)

我们试图获得第999个元素Stream.这是低效的,因为这个对象与以前的对象相同,所以我们浪费了时间来制作它.我们将继续浪费时间和记忆,制作1000个相同的Cons细胞.(请原谅可怕的画作.)

第一个版本的图表

现在,定义constant第二种方式.

constant(something)
{ lazy val self = Cons(something, self); self }
Run Code Online (Sandbox Code Playgroud)

现在,您Stream只需要参考自己.弄清楚这一点Stream并不能创造出新的Cons细胞; 它只返回原始流(self.tail eq self),这意味着你不浪费任何内存,时间成本下降,因为你也不浪费时间分配和填充内存.

第二个版本的图表

  • 感谢您的时间和这个详细的解决方案。顺便说一句,美妙的图画:) (2认同)