Monday, October 26, 2015

Early-termination foldLeft for Scala Streams

The foldRight and foldLeft methods for Scala Streams cannot terminate early, so here is my attempt to provide that functionality through the “enrich my library” pattern:

  implicit class StreamWithLazyFold[A](s: Stream[A]) {
    def foldLeft1[B](z: B)(f: (B, A) => (B, Boolean)): B = s match {
      case _ if s.isEmpty => z
      case h #:: t => {
        val (z1, stop) = f(z, h.asInstanceOf[A])
        if(stop) z1
        else t.asInstanceOf[Stream[A]].foldLeft1(z1)(f)
      }
    }
  }

Test:

  s.foldLeft1(true)((x, y) => {
    println("run!")
    val b = (y < 3) && x
    (b, !b)
  })

It prints “run!” only 3 times.

0 comments: