简体   繁体   English

scala中的函数编程 - 无限流

[英]Functional programming in scala - infinite streams

I'm working through the exercises and concepts of the book: Functional Programming in Scala. 我正在完成本书的练习和概念:Scala中的函数编程。 Say I need to define a constant function, which returns an infinite stream by the given value. 假设我需要定义一个constant函数,它按给定值返回一个无限流。

Here is my version: 这是我的版本:

def constant[A](a: A): Stream[A] = Stream.cons(a, constant(a))

and the answer in GitHub : GitHub中的答案:

def constant[A](a: A): Stream[A] = {
  lazy val tail: Stream[A] = Cons(() => a, () => tail)
  tail
}

The comment says the latter is more efficient than the former since it's just one object referencing itself. 评论说后者比前者更有效,因为它只是一个引用自身的对象。 I can't understand this, any help would be greatly appreciated. 我无法理解这一点,任何帮助都将不胜感激。 (and sorry for my broken English :) (抱歉我的英语不好:)

Say you define constant the first way. 假设您定义第一种方式的constant Now, 现在,

constant(something)

This is one Cons cell, and it has a reference to the lazy values something and constant(something) 这是一个Cons细胞,并且它具有与懒惰值的参考somethingconstant(something)

Cons(() => something, () => constant(something))

Now, let's try to get the 1000th element. 现在,让我们尝试获得第1000个元素。 We need to evaluate the tail, because we need to go deeper than just the first element. 我们需要评估尾部,因为我们需要比第一个元素更深入。 So, we execute constant(something) , and we get a new Cons cell that looks just like the original: 所以,我们执行constant(something) ,然后我们得到一个看起来像原始的新的 Cons单元格:

Cons(() => something, () => constant(something))

And we try to get 999th element of this Stream . 我们尝试获得此Stream第999个元素。 This is inefficient, because this object is the same as the one from before, so we just wasted our time making it. 这是低效的,因为这个对象与以前的对象相同,所以我们浪费了时间来制作它。 We will continue to waste time and memory making 1000 identical Cons cells. 我们将继续浪费时间和记忆,制作1000个相同的Cons细胞。 (Excuse the terrible drawing.) (请原谅可怕的画作。)

第一个版本的图表

Now, define constant the second way. 现在,定义第二种方式的constant

constant(something)
{ lazy val self = Cons(something, self); self }

Now, your Stream simply has a reference to itself. 现在,您的Stream只是对自己的引用。 Getting the tail of this Stream does not create a new Cons cell; 获得此Stream的尾部不会创建新的Cons单元格; it simply returns the original stream ( self.tail eq self ), which means you waste no memory, and the time cost goes down because you also don't waste time allocating and filling that memory. 它只返回原始流( self.tail eq self ),这意味着你不浪费任何内存,时间成本下降,因为你也不浪费时间分配和填充内存。

第二个版本的图表

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM