【问题标题】:Scala Stream Off By OneScala Stream Off By One
【发布时间】:2012-11-23 16:12:07
【问题描述】:

有人可以解释一下 REPL 的以下输出吗?

我正在定义 2 个(无限)流,它们在其他方面的定义相同,只是 map 在一个定义中以 .(句点)开头,而 _ (空间)在另一个。

我可以看到这会导致 map 以不同的方式绑定,但是第二个定义的输出中的 1 会发生什么?

谢谢。

scala> lazy val infinite: Stream[Int] = 1 #:: infinite.map(_+1)
infinite: Stream[Int] = <lazy>

scala> val l = infinite.take(10).toList.mkString(",")
l: String = 1,2,3,4,5,6,7,8,9,10

scala> lazy val infinite2: Stream[Int] = 1 #:: infinite2 map(_+1)
infinite2: Stream[Int] = <lazy>

scala> val l2 = infinite2.take(10).toList.mkString(",")
l2: String = 2,3,4,5,6,7,8,9,10,11

【问题讨论】:

    标签: scala map stream


    【解决方案1】:

    关于method associativity。这个:

    1 #:: infinite.map(_+1)
    

    这很简单:

    1 #:: infinite2 map(_+1)
    

    被编译器解释为:

    (1 #:: infinite2) map(_+1)
    

    1 #:: infinite2 是您想要的流,但在返回它之前,您应用惰性转换为每个项目添加一个。这解释了为什么 1 从未作为结果出现 - 转换后它变为 2。

    更多详情请见:Operator precedence in Scala。由于# 不是特殊字符,因此它与map 同等对待,因此方法从左到右进行评估。

    【讨论】:

    • @BillBarrington:没问题。如果您的问题得到解决,请接受/支持这个或其他答案。
    【解决方案2】:

    在infinite2的情况下,你所表达的等价于:

    lazy val infinite2: Stream[Int] = (1 #:: infinite2) map(_ + 1)
    

    由于流是从 1 开始的,所以 map 会在第一个元素上加 1。

    【讨论】:

      猜你喜欢
      • 2012-05-10
      • 2014-09-13
      • 2013-04-30
      • 2015-08-26
      • 1970-01-01
      • 1970-01-01
      • 2019-03-27
      • 2018-08-17
      • 1970-01-01
      相关资源
      最近更新 更多