package laziness sealed trait Stream[+A] { import Stream._ def toList: List[A] = ??? def take(n: Int): Stream[A] = ??? //This can be tailrecursive. Uncomment below to let the compiler check //@annotation.tailrec def drop(n: Int): Stream[A] = ??? // Methods shown during lecture def headOption: Option[A] = this match { case Cons(h, _) => Some(h()) case Empty => None } def exists(p: A => Boolean): Boolean = this match { case Cons(x, xs) => p(x()) || xs().exists(p) case Empty => false } def foldRight[B](z: => B)(f: (A, => B) => B): B = this match { case Cons(x, xs) => f(x(), xs().foldRight(z)(f)) case Empty => z } } case object Empty extends Stream[Nothing] case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A] object Stream { // companion object def fibs: Stream[Int] = { // tip: write a recursive def here and call it with some start values ??? } def unfold[A, S](z: S)(f: S => Option[(A, S)]): Stream[A] = ??? def fibsViaUnfold: Stream[Int] = ??? // Methods shown during Lecture def cons[A](h: => A, t: => Stream[A]): Stream[A] = { lazy val head = h lazy val tail = t Cons(() => head, () => tail) } def empty[A]: Stream[A] = Empty def apply[A](as: A*): Stream[A] = if (as.isEmpty) empty else cons(as.head, apply(as.tail: _*)) val ones: Stream[Int] = cons(1, ones) }