Friday, October 16, 2015

Traversable vs Iterable

Traversable features foreach , which does not return anything, while Iterable features iterate which returns a kind of collection that contains every element in the data structure.

// scala code
object Tools {
  def time[R](block: => R): R = {
    val t0 = System.nanoTime()
    val result = block // call-by-name
    val t1 = System.nanoTime()
    println("Elapsed time: " + (t1 - t0) / 1e9 + "s")
    result
  }

  implicit class ListSafeTailInit[A](val list: List[A]) {
    def tailOption: Option[List[A]] = {
      if (list.isEmpty) None else Some(list.tail)
    }

    def initOption: Option[List[A]] = {
      if (list.isEmpty) None else Some(list.init)
    }
  }

}

object Example1 {
  sealed abstract class Tree extends Traversable[Int] {
    def foreach[U](f: Int => U): Unit = this match {
      case Node(elem) => f(elem)
      case Branch(l, r) => {
        l.foreach(f)
        r.foreach(f)
      }
    }
  }

  case class Branch(left: Tree, right: Tree) extends Tree

  case class Node(elem: Int) extends Tree

}

object Example2 {

  case class Node(elem: Int) extends Tree
  case class Branch(left: Tree, right: Tree) extends Tree

  sealed abstract class Tree extends Iterable[Int] {
    def iterator: Iterator[Int] = this match {
      case Node(elem) => Iterator.single(elem)
      // the ++ operation is expensive here
      case Branch(l, r) => l.iterator ++ r.iterator
    }
  }
}




object Test {
  val xs = List(1, 2, 3, 4, 5, 6)
  val git = xs grouped 3
  git.next
  git.next()
  git.next()
  // error, only two elems in git
  val slid = xs sliding(5, 1)
  slid.next() // List(1, 2, 3, 4, 5)
  slid.next() // List(2, 3, 4, 5, 6)
  slid.next()
  // error
  // subcollections
  val x = 1 to 10
  x.takeRight(5)
}

0 comments: