Lazily evaluated indexed sequence type

放肆的年华 提交于 2019-11-30 18:43:56

Strange, Miles recently tweeted about this. A reply then points out to Need at the end of Name.scala in scalaz and another one points to specs' LazyParameter.

Little testing with Need:

import scalaz._
import Scalaz._
val longOp = { var x = 0; () => {println("longOp"); x += 1; x }}
val seq = Seq(Need(longOp()), Need(longOp()))
val sum = seq.map(_.value).sum
val sum = seq.map(_.value).sum

val v = Need(longOp())
val s = v.map("got " + _)
println(s.value)
println(s.value)

prints:

longOp: () => Int = <function0>
seq: Seq[scalaz.Name[Int]] = List(
  scalaz.Name$$anon$2@1066d88, scalaz.Name$$anon$2@1011f1f)
longOp
longOp
sum: Int = 3
sum: Int = 3
v: scalaz.Name[Int] = scalaz.Name$$anon$2@133ef6a
s: scalaz.Name[java.lang.String] = scalaz.Name$$anon$2@11696ec
longOp
got 3
got 3

So longOp is only called once on first access of value.

To my knowledge, there's nothing that fit in the standard library. A solution might be to use a kind of Lazy wrapper for your objects:

class Lazy[A](operation: => A) {
  lazy val get = operation
}

And then you can build your Collection[Lazy[A] with any kind of collection you want to use.

It sounds like you want a Stream.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!