Scala中惰性流的第一个元素

Scala中惰性流的第一个元素,scala,functional-programming,stream,lazy-evaluation,scala-streams,Scala,Functional Programming,Stream,Lazy Evaluation,Scala Streams,下面是一个简单的例子,我可以定义一个函数,通过 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, ?) 在这个简单的例子中,我

下面是一个简单的例子,我可以定义一个函数,通过

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
                                      ^
scala>(整数取10)最后一个
res27:Int=11
scala>整数最后取10
:24:错误:未找到:最后一个值
整数最后取10
^

我觉得把东西用括号括起来很麻烦,有没有我不知道的速记法?

你可能在想:
1::整数映射(x=>nextingeger(x))
被解析为
1::(整数映射(x=>nextingeger(x))
,而实际上它被解析为
(1::整数)。map(x=>nextingeger(x))
。添加paren可以解决您的问题:

val integers: Stream[Int] = 1 #:: (integers map nextInteger)
(请注意,由于
nextInteger
只是一个函数,因此不需要为其生成lambda,而且
Stream
已经是惰性的,因此不需要生成
整数
惰性)


至于你的编辑,看看关于这个问题的优秀答案。简言之:没有简单的方法。问题是,除非你已经知道所涉及的函数的算术性,否则下一个阅读你的代码的人会觉得像你所建议的那样工作是地狱。。。比如说,

myList foo bar baz

可能是
myList.foo.bar.baz
以及
myList.foo(bar.baz
,如果不检查
foo
bar
baz
的定义,您就不会知道。Scala决定消除这种模糊性——它总是后者。

你可能认为
1::整数映射(x=>nextingeger(x))
被解析为
1::(整数映射(x=>nextingeger(x))
,而实际上它被解析为
(1::整数)。map(x=>nextingeger(x))
。添加paren可以解决您的问题:

val integers: Stream[Int] = 1 #:: (integers map nextInteger)
(请注意,由于
nextInteger
只是一个函数,因此不需要为其生成lambda,而且
Stream
已经是惰性的,因此不需要生成
整数
惰性)


至于你的编辑,看看关于这个问题的优秀答案。简言之:没有简单的方法。问题是,除非你已经知道所涉及的函数的算术性,否则下一个阅读你的代码的人会觉得像你所建议的那样工作是地狱。。。比如说,

myList foo bar baz

可能是
myList.foo.bar.baz
以及
myList.foo(bar.baz
,如果不检查
foo
bar
baz
的定义,您就不会知道。Scala决定消除这种模糊性——总是后者。

啊,太好了,谢谢。你也可以评论我的语法编辑吗?啊,太好了,谢谢。你也可以评论我的语法编辑吗?人们使用括号的原因是为了避免这样的事情<代码>1::整数映射(x=>nextInteger(x))实际上是
(1::整数)。映射(x=>nextInteger(x))
。原因是
#::
是左关联的。我可以建议和推荐的缩写是:
(integers take 10 toList)last
integers.take(10).toList.last
死亡笔记是一个很好的例子人们之所以使用括号来避免这样的事情<代码>1::整数映射(x=>nextInteger(x))实际上是
(1::整数)。映射(x=>nextInteger(x))
。原因是
#::
是左关联的。我可以建议和推荐的缩写是:
(integers take 10 toList)last
integers.take(10).toList.last
死亡笔记是一个很好的展示