Stream generators (original) (raw)

Joe Bowbeer joe.bowbeer at gmail.com
Fri Nov 30 12:38:16 PST 2012


Here are two examples of methods that combine two streams:

  1. An addStreams method, like the one below written in Python that generates a stream by summing two other streams:

    def addStreams(si, sj): # add corres. elements of two streams if not si: return sj if not sj: return si tailsum = lambda ti=si, tj=sj : addStreams(tail(ti), tail(tj)) return (head(si) + head(sj), tailsum)

Source:

http://code.activestate.com/lists/python-list/9029/

  1. A merge method, like the one below written in Scala that generates Hamming numbers:

def hamming: Stream[Int] = Stream.cons(1, merge(hamming.map(2*), merge(hamming.map(3*), hamming.map(5*))))

Where the merge method is defined:

def merge[T](a: Stream[T], b: Stream[T])(implicit ord: Ordering[T]): Stream[T] = { if (b.isEmpty) a else if (a.isEmpty) b else { val order = ord.compare(a.head, b.head) if (order < 0) Stream.cons(a.head, merge(a.tail, b)) else if (order > 0) Stream.cons(b.head, merge(a, b.tail)) else Stream.cons(a.head, merge(a.tail, b.tail)) } }

Source:

http://code.google.com/p/wing-ding/source/browse/trunk/books/Programming_Scala/src/adhoc/HammingNumbers/src/hamming/Main.scala

Is it easy to write the corresponding methods in Java?

Joe

On Fri, Nov 30, 2012 at 10:09 AM, Joe Bowbeer <joe.bowbeer at gmail.com> wrote:

I mean a more general merge which may emit an element from either stream, depending, and may drop some elements from one or both streams. On Nov 30, 2012 9:51 AM, "Brian Goetz" <brian.goetz at oracle.com> wrote:

I think it would be beneficial for comparison to show a bit of their implementations.

Here's iterate(seed, UnaryOperator): public static Stream iterate(final T seed, final UnaryOperator f) { Objects.requireNonNull(f); final InfiniteIterator iterator = new InfiniteIterator() { T t = null; @Override public T next() { return t = (t == null) ? seed : f.operate(t); } }; return stream(new StreamSource.ForIterator<>(**iterator), StreamOpFlag.ISORDERED); } Not too difficult. But, the idea is to make things that are easy in the header of a for-loop to be easy as the source of a stream. repeat(n) in Scheme is about 10 characters. Yeah, well this is Java... How difficult is it to implement a merge, as might be needed to generate Hamming numbers? (One of my favorite test cases.) You mean, interleave two streams? That's on our list to implement as Streams.interleave(a, b). Is there a method to limit a stream to a length? If so then one of your methods may be extra baggage. Yes: stream.limit(n).



More information about the lambda-libs-spec-observers mailing list