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
死亡笔记是一个很好的展示