Friday, January 22, 2010

Streams 2: Stream construction

This post just adds to the information about streams in the previous post Introducing Streams. In this topic the methods in the Stream object are looked at a little closer:
(standard warning. Examples were done in Scala 2.8 so some examples may need to be modified for Scala 2.7)
  1. scala> import Stream._
  2. import Stream._
  3. // the empty stream.  good for terminating a stream
  4. scala> empty        
  5. res0: scala.collection.immutable.Stream[Nothing] = Stream()
  6. // one way to declare a stream. 
  7. scala> 1 #:: 2 #:: empty foreach (println _)
  8. 1
  9. 2
  10.  // the other main way to create a stream
  11. scala> cons(1, cons(2, empty)) foreach println
  12. 1
  13. 2
  14. /*
  15. Neither of the previous methods of stream creation are particularily useful because they are explicit and therefore they may as well be Lists or some other collection.  There is very little benefit in those cases.  However when the cons of a stream (tail) is defined as a function then things get a bit more interesting
  16. */
  17. scala> def i(x:Int,y:Int):Stream[Int] = (x*y) #:: i(x+1,y*2)
  18. i: (x: Int,y: Int)Stream[Int]
  19. scala> i(2,3) take 3 foreach println
  20. 6
  21. 18
  22. 48
  23. // now lets visit a few more methods in the Stream object
  24. // create an infinite stream starting at 10
  25. scala> from (10) take 3 foreach println     
  26. 10
  27. 11
  28. 12
  29. // an infinite stream starting at 10 an increasing by 3
  30. scala> from (10,3) take 3 foreach println
  31. 10
  32. 13
  33. 16
  34. // converting an interator to a stream
  35. scala> (1 until 4).iterator.toStream foreach println
  36. 1
  37. 2
  38. 3
  39. // creating an Iterable to a stream
  40. scala> (1 until 4).toStream foreach println         
  41. 1
  42. 2
  43. 3
  44. // a stream that always returns 7
  45. // the following is a pretty convoluted way to compute 7*49 :-P
  46. scala> continually(7) take 49 reduceLeft {_ + _}
  47. res10: Int = 343
  48. // create a stream of 6 streams
  49. scala> fill(6)(1 to 2 toStream) foreach println
  50. Stream(1, ?)
  51. Stream(1, ?)
  52. Stream(1, ?)
  53. Stream(1, ?)
  54. Stream(1, ?)
  55. Stream(1, ?)
  56. /*
  57. create the same stream as the last example but flatten it out so instead of being a stream of 6 streams it is a stream of 12 elements. Each element in each of the streams are visited in order
  58. */
  59. scala> fill(6)(1 to 2 toStream).flatten take 6 foreach println
  60. 1
  61. 2
  62. 1
  63. 2
  64. 1
  65. 2
  66. /*
  67. equivalent to:
  68. (1 until 20 by 3).toStream foreach println
  69. */
  70. scala> range(1, 20, 3) foreach println
  71. 1
  72. 4
  73. 7
  74. 10
  75. 13
  76. 16
  77. 19
  78. /*
  79. equivalent to
  80. (1 until 3).toStream foreach println
  81. */
  82. scala> range(1,3) foreach println          
  83. 1
  84. 2
  85. /*
  86. iterate is fun! 
  87. signature is iterator(start)(elem)
  88. basically starting at 3 execute the function on the previous value in the stream.
  89. This is an infinite stream
  90. */
  91. scala> iterate(3){i => i-10} take 5 foreach println _               
  92. 3
  93. -7
  94. -17
  95. -27
  96. -37
  97. /*
  98. Another example
  99. */
  100. scala> iterate(3){i => i*2} take 5 foreach println _ 
  101. 3
  102. 6
  103. 12
  104. 24
  105. 48
  106. /*
  107. A final example
  108. */
  109. scala> iterate(3){i => i} take 5 foreach println _  
  110. 3
  111. 3
  112. 3
  113. 3
  114. 3
  115. /*
  116. The real final,final example.  This example uses the optional length parameter.   So the stream is restricted to 5 elements
  117. */
  118. scala> iterate(3,5){i => i} foreach println       
  119. 3
  120. 3
  121. 3
  122. 3
  123. 3

2 comments:

  1. Hello, this is very helpful :) I use it alot!

    ReplyDelete
  2. Wow, way to make myself sound like a spambot lol. Particularly the #:: notation is beneficial :)

    ReplyDelete