Scala lazy

trait Stream[+A] {
  def uncons: Option[(A, Stream[A])]
  def isEmpty: Boolean = uncons.isEmpty

  // 此函数有side effect很不好, 不要这样写, 这里只为测试,
  def tryMatch: Unit = {
    uncons match {
      case Some(x) => {
        // x._2.tryMatch
        println("some:"+x)
      }
      case None => println("none")
    }

  }
}

case object Empty extends Stream[Nothing] {
  def uncons = None
}
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A] {
  def uncons = Some((h(), t()))
}

object Stream {
  def empty[A]: Stream[A] =
    new Stream[A] { def uncons = None }
  def cons[A](hd: => A, tl: => Stream[A]): Stream[A] =
    new Stream[A] {
      lazy val uncons = {
        println("called")
        Some((hd, tl))
      }
    }
  def apply[A](as: A*): Stream[A] =
    if (as.isEmpty) empty
    else cons(as.head, apply(as.tail: _*))

  def tryConstruct[A](hd: => A, tl: => Stream[A]): Stream[A] = {
    lazy val head = {println("head");hd}
    lazy val tail = {println("tail");tl}
    Cons(() => head, () => tail)
  }
}

object LazyStream {

  def main(args: Array[String]) : Unit= {
    // Part1
    Stream[String]("a", "b", "c", "d").tryMatch
    // Part2
    Stream.tryConstruct("e", Stream[String]("a", "b", "c", "d")) match {
      case Cons(h, t) => h()
      case Empty => println("empty")
    }
  }
}

Part1

x._2.tryMatch 不注释的打印结果

called
called
called
called
none
some:(d,Stream$$anon$1@e9e54c2)
some:(c,Stream$$anon$2@65ab7765)
some:(b,Stream$$anon$2@1b28cdfa)
some:(a,Stream$$anon$2@eed1f14)

x._2.tryMatch 注释掉的打印结果

called
some:(a,Stream$$anon$2@e9e54c2)

可见,b,c,d只在被明确调用的时候才被构造,否则以整体 Stream$$anon$2@e9e54c2 的形式显示。 Some(x) 的时候a就被构造了 called 就被打印出来

Part2

  def tryConstruct[A](hd: => A, tl: => Stream[A]): Stream[A] = {
    lazy val head = {println("head");hd}
    lazy val tail = {println("tail");tl}
    Cons(() => head, () => tail)
  }

打印结果

head

虽然head作为返回值被返回,但是 () => head 这个函数并没有被调用,不被evaluate。因此,如果只Stream.tryConstruct("e", Stream[String]("a", "b", "c", "d"))的话,是不会打印出东西的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值