这里是一个最小的例子,我可以定义一个函数,通过
给出我的下一个整数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
^
我发现在括号里包装东西很麻烦,有我不知道的速记吗?
您可能认为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
设置为惰性)
至于你的编辑,请看这个关于这个问题的极好的答案。简而言之:没有捷径可走。问题是,除非你已经知道所涉及的函数的重要性,否则对于下一个阅读你代码的人来说,你所建议的工作将是地狱……例如
myList foo bar baz
可能是myList.foo.bar.baz
和myList.foo(bar).baz
,如果不检查foo
, bar
和baz
的定义,您将无法知道。Scala决定消除这种歧义——总是后者。