Scala流的行为违反直觉

  • 本文关键字:直觉 Scala scala stream
  • 更新时间 :
  • 英文 :


我在玩Scala的流,我不确定我是否理解这个想法。让我们考虑以下代码

def fun(s: Stream[Int]): Stream[Int] = Stream.cons(s.head, fun(s.tail))

执行这个

val f = fun(Stream.from(7))
f take 14 foreach println

结果

7 8 9 10 ... up to 20

假设我理解这一点。

现在,稍微更改代码(头上加2)

def fun(s: Stream[Int]): Stream[Int] = Stream.cons(s.head + 2, fun(s.tail))

中的结果

9 10 11 ... up to 22

我想我又明白了。问题从下一个例子开始(d

def fun(s: Stream[Int]): Stream[Int] = Stream.cons(s.head / 2, fun(s.tail))
3 4 4 5 5 6 6 7 7 8 8 9 9 10

我不明白,请解释为什么会这样?类似地,减法也没有像我预期的那样表现

def fun(s: Stream[Int]): Stream[Int] = Stream.cons(s.head - 2, fun(s.tail))

输出

5 6 7 8 9 10 ... up to 18

给定您的"take":7 8 9 10 ... up to 20

  • 当您在每个元素上+ 2时会发生什么?

  • 当你在每个元素上/ 2int算术)时会发生什么?

  • 在每个元素上- 2时会发生什么?

如果您将其视为映射Stream,会更直观吗?

scala> val s1 = Stream.from(10)
s1: scala.collection.immutable.Stream[Int] = Stream(10, ?)
scala> val s2 = s1 map (_ * 2)
s2: scala.collection.immutable.Stream[Int] = Stream(20, ?)
scala> s2.take(5).toList
res0: List[Int] = List(20, 22, 24, 26, 28)
scala> val s3 = s1 map (_ / 2)
s3: scala.collection.immutable.Stream[Int] = Stream(5, ?)
scala> s3.take(5).toList
res1: List[Int] = List(5, 5, 6, 6, 7)
scala> val s4 = s1 map (_ - 2)
s4: scala.collection.immutable.Stream[Int] = Stream(8, ?)
scala> s4.take(5).toList
res2: List[Int] = List(8, 9, 10, 11, 12)

好的,让我们试着把它分解。。。

def fun(s: Stream[Int]): Stream[Int] = Stream.cons(s.head, fun(s.tail))

是一个函数,它取一个Stream,将其headtail分离,递归地应用于tail,然后用cons运算符重新组合这两个结果。

由于在该操作期间head没有被触摸,因此Stream被逐个地重建为以前的样子。

val f = fun(Stream.from(7))

f它与Stream.from(7)相同[即从7开始的递增整数的无限序列]

打印f take 14实际上表明,我们有从7开始的前14个数字[即7,8,9,…,20]

接下来发生的是,当用cons重建流时,每个元素都会以某种方式修改

def fun(s: Stream[Int]): Stream[Int] = Stream.cons(s.head + 2, fun(s.tail))

在将head与修饰的tail重组之前将其添加2。后者以相同的方式进行修改,其第一个元素被添加到2,然后重新组合到其自己的tail,因此也是自己的。

如果我们再次假设s包含从7开始的数字,则发生的情况看起来像

fun(s) = cons(7 + 2, cons(8 + 2, cons(9 + 2, ... ad infinitum ... )))))

这与向流CCD_ 22的每个元素添加2相同。

代码通过打印"9到22"来确认这一点,确切地说是"7到20",每个元素都添加了2。

其他例子类似:

  • 每个元素的流除以2(并四舍五入到地板整数值,因为Stream是用Int值键入的)
  • 每个元素递减2的流

相关内容

  • 没有找到相关文章

最新更新