【问题标题】:Lazy Evaluation in a Stream?流中的惰性评估?
【发布时间】:2015-05-29 22:33:47
【问题描述】:

给定一个lazy val

scala> lazy val y = {println("Y!"); 200}
y: Int = <lazy>

我尝试将y 放入Stream - 以了解它是否会被急切或懒惰地评估。

scala> Stream(100, y)
Y!
res4: scala.collection.immutable.Stream[Int] = Stream(100, ?)

显然它已被热切地评估。

除了以下内容,我如何创建一个懒惰地评估其成员的Stream

scala> Stream[() => Int](() => 100, () => 200)
res18: scala.collection.immutable.Stream[() => Int] = Stream(<function0>, ?)

scala> res18.map(_())
res19: scala.collection.immutable.Stream[Int] = Stream(100, ?)

scala> res19.last
res20: Int = 200

scala> res19
res21: scala.collection.immutable.Stream[Int] = Stream(100, 200)

【问题讨论】:

    标签: scala stream


    【解决方案1】:

    特拉维斯是对的,但只是为了好玩:

    scala> implicit def a2f[T](t : => T) : (() => T) = () => t
    a2f: [T](t: => T)() => T
    
    scala> def lazyStream[T]( args : (() => T)* ) : Stream[T] = Stream(args:_*).map(_())
    lazyStream: [T](args: () => T*)Stream[T]
    
    scala> lazy val y = {println("Y!"); 200}
    y: Int = <lazy>
    
    scala> lazyStream(100, y)
    res8: Stream[Int] = Stream(100, ?)
    
    scala> res8.last
    Y!
    res9: Int = 200
    

    【讨论】:

    • 我不确定我是否想让1() 开始有意义。 :)
    • :) 是的,我绝对应该用“实际上不要这样做”来注释这些恶作剧。
    【解决方案2】:

    Stream.apply 采用可变参数,并且在 Scala 中不可能有按名称可变参数。不过,您可以对流使用 #:: 语法:

    scala> lazy val y = {println("Y!"); 200}
    y: Int = <lazy>
    
    scala> val s = 100 #:: y #:: Stream.empty
    s: scala.collection.immutable.Stream[Int] = Stream(100, ?)
    
    scala> s.last
    Y!
    res0: Int = 200
    

    之所以有效,是因为 ConsWrapper 类和用于将 #:: 添加到流中的隐式转换都采用名称参数。

    【讨论】:

      猜你喜欢
      • 2014-02-08
      • 1970-01-01
      • 1970-01-01
      • 2020-07-18
      • 1970-01-01
      • 2013-03-11
      • 2017-01-18
      • 2018-11-11
      相关资源
      最近更新 更多