def unfold[A,S](initial: S)(generateNext: S => Option[(A, S)]): Stream[A] = generateNext(initial) match { case Some((first, next)) => cons(first, unfold(next)(generateNext)) case None => empty } val fibs = unfold((0,1)) { case (f0, f1) => Some((f0, (f1, f0+f1))) } def from(n: Int) = unfold(n)(n => Some(n, n+1)) def constant[A](a: A) = unfold(a)(_ => Some((a, a)))