Created
November 2, 2011 16:06
-
-
Save aloiscochard/1334040 to your computer and use it in GitHub Desktop.
Scala [In]finite Stream Constructor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Stream._ | |
/** A possibly finite stream that repeatedly applies a given function to a start value. | |
* | |
* @param start the start value of the stream | |
* @param f the function that's repeatedly applied | |
* @return the stream returning the possibly finite sequence of values `start, f(start), f(f(start)), ...` | |
*/ | |
def iterate[A](f: A => A, a: A): Stream[A] = unfold((x: A) => Some((x, f(x))), a) | |
def unfold[A, B](start: B)(f: B => Option[Tuple2[A,B]]): Stream[A] = f(start) match { | |
case Some((elem, next)) => elem #:: unfold(next)(f) | |
case None => empty | |
} | |
// Could be integrated here -> https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_9_1_final/src//library/scala/collection/immutable/Stream.scala#L647 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@cvogt for anything where it doesn't make sense to keep asking for stuff indefinitely. In your example,
+1
doesn't care if you keep running it forever, so you're safe with an intermediate infinite stream, but in many more realistic use cases, you have a process that you're going to have to repeat until some condition stops being true, and then you need to stop, and that's based on a piece of internal state that is no longer accessible by the time you usetakeWhile
. A simple example of a good use case here is a pagination API that hands you a "marker" telling you how to ask for more. You can't just keep asking for more forever and filter later.Also,
unfold
is in some senses the most fundamental operation on aStream
, much like howfold
(right) is a fundamental operation onList
.