Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Streams for iteration in Scala

Tags:

stream

scala

SICP says that iterative processes (e.g. Newton method of square root calculation, "pi" calculation, etc.) can be formulated in terms of Streams.

Does anybody use streams in Scala to model iterations?

like image 502
Michael Avatar asked Dec 19 '11 19:12

Michael


People also ask

What is the difference between a stream and an iterator?

Iterators, in Java, are used in Collection Framework to retrieve elements one by one. A stream in Java is a pipeline of objects from an array or a collection data source. A sequential stream is one in which the objects are pipelined in a single stream on the same processing system.

Is Scala iterator lazy?

Unlike operations directly on a concrete collection like List , operations on Iterator are lazy.

What is a stream in Scala?

The Stream is a lazy lists where elements are evaluated only when they are needed. This is a scala feature. Scala supports lazy computation. It increases performance of our program. Streams have the same performance characteristics as lists.

Which expression is one way to iterate over a collection and generate a collection of each iteration result?

forEach() method is available in Java 8 and each collection has this method that implements the iteration internally.


1 Answers

Here is one way to produce the stream of approximations of pi:

val naturals = Stream.from(0) // 0, 1, 2, ...
val odds = naturals.map(_ * 2 + 1) // 1, 3, 5, ...
val oddInverses = odds.map(1.0d / _) // 1/1, 1/3, 1/5, ...
val alternations = Stream.iterate(1)(-_) // 1, -1, 1, ...
val products = (oddInverses zip alternations)
      .map(ia => ia._1 * ia._2) // 1/1, -1/3, 1/5, ...

// Computes a stream representing the cumulative sum of another one
def sumUp(s : Stream[Double], acc : Double = 0.0d) : Stream[Double] =
  Stream.cons(s.head + acc, sumUp(s.tail, s.head + acc))

val pi = sumUp(products).map(_ * 4.0) // Approximations of pi.

Now, say you want the 200th iteration:

scala> pi(200)
resN: Double = 3.1465677471829556

...or the 300000th:

scala> pi(300000)
resN : Double = 3.14159598691202
like image 162
Philippe Avatar answered Oct 07 '22 17:10

Philippe