Scala 惰性流的第一个元素
First Element of a Lazy Stream in Scala
这是一个最小的例子,我可以定义一个函数,通过
给出我的下一个整数
def nextInteger(input: Int): Int = input+1
然后我可以将惰性整数流定义为
lazy val integers: Stream[Int] = 1 #:: integers map(x=>nextInteger(x))
令我惊讶的是,这个流的第一个元素是 2 而不是 1
scala> integers
res21: Stream[Int] = Stream(2, ?)
在这个简单的例子中,我可以在整数定义中使用 0 而不是 1 来实现我想要的结果,但是通常如何设置一个流来使初始值不丢失?在我的例子中,我正在设置一个迭代算法并且想知道初始值。
编辑:
此外,我从未理解导致以下语法失败的设计选择:
scala> (integers take 10 toList) last
res27: Int = 11
scala> integers take 10 toList last
<console>:24: error: not found: value last
integers take 10 toList last
^
我觉得用括号括起来很麻烦,有没有shorthand我不知道的?
您可能认为 1 #:: integers map(x=>nextInteger(x))
被解析为 1 #:: (integers map(x=>nextInteger(x)))
,而实际上它被解析为 (1 #:: integers).map(x=>nextInteger(x))
。添加括号可以解决您的问题:
val integers: Stream[Int] = 1 #:: (integers map nextInteger)
(注意因为 nextInteger
只是一个函数,你不需要为它做一个 lambda,并且因为 Stream
已经是惰性的,所以让 integers
惰性是不必要的)
关于您的编辑,请查看 this 对此事的出色回答。简而言之:没有简单的方法。问题是,除非您已经知道所涉及的功能的多样性,否则对于下一个阅读您代码的人来说,像您建议的那样工作将是地狱……例如,
myList foo bar baz
可能是 myList.foo.bar.baz
以及 myList.foo(bar).baz
,如果不检查 foo
、bar
和 baz
的定义,您将不会知道. Scala 决定消除这种歧义——它总是后者。
这是一个最小的例子,我可以定义一个函数,通过
给出我的下一个整数def nextInteger(input: Int): Int = input+1
然后我可以将惰性整数流定义为
lazy val integers: Stream[Int] = 1 #:: integers map(x=>nextInteger(x))
令我惊讶的是,这个流的第一个元素是 2 而不是 1
scala> integers
res21: Stream[Int] = Stream(2, ?)
在这个简单的例子中,我可以在整数定义中使用 0 而不是 1 来实现我想要的结果,但是通常如何设置一个流来使初始值不丢失?在我的例子中,我正在设置一个迭代算法并且想知道初始值。
编辑: 此外,我从未理解导致以下语法失败的设计选择:
scala> (integers take 10 toList) last
res27: Int = 11
scala> integers take 10 toList last
<console>:24: error: not found: value last
integers take 10 toList last
^
我觉得用括号括起来很麻烦,有没有shorthand我不知道的?
您可能认为 1 #:: integers map(x=>nextInteger(x))
被解析为 1 #:: (integers map(x=>nextInteger(x)))
,而实际上它被解析为 (1 #:: integers).map(x=>nextInteger(x))
。添加括号可以解决您的问题:
val integers: Stream[Int] = 1 #:: (integers map nextInteger)
(注意因为 nextInteger
只是一个函数,你不需要为它做一个 lambda,并且因为 Stream
已经是惰性的,所以让 integers
惰性是不必要的)
关于您的编辑,请查看 this 对此事的出色回答。简而言之:没有简单的方法。问题是,除非您已经知道所涉及的功能的多样性,否则对于下一个阅读您代码的人来说,像您建议的那样工作将是地狱……例如,
myList foo bar baz
可能是 myList.foo.bar.baz
以及 myList.foo(bar).baz
,如果不检查 foo
、bar
和 baz
的定义,您将不会知道. Scala 决定消除这种歧义——它总是后者。