1
1
sealed trait Stream [+ A ] {
2
2
import Stream ._
3
3
4
- def headOption : Option [A ] = this match {
5
- case Empty => None
6
- case Cons (h, t) => Some (h())
7
- }
4
+ def headOption : Option [A ] =
5
+ this match {
6
+ case Empty => None
7
+ case Cons (h, t) => Some (h())
8
+ }
8
9
9
10
def headOptionWithFoldRight : Option [A ] =
10
11
foldRight(None : Option [A ])((a, _) => Some (a))
@@ -19,22 +20,24 @@ sealed trait Stream[+A] {
19
20
loop(this , Nil ).reverse
20
21
}
21
22
22
- def take (n : Int ): Stream [A ] = this match {
23
- case Cons (h, t) if n > 1 => cons(h(), t().take(n - 1 ))
24
- case Cons (h, _) if n == 1 => cons(h(), empty)
25
- case _ => empty
26
- }
23
+ def take (n : Int ): Stream [A ] =
24
+ this match {
25
+ case Cons (h, t) if n > 1 => cons(h(), t().take(n - 1 ))
26
+ case Cons (h, _) if n == 1 => cons(h(), empty)
27
+ case _ => empty
28
+ }
27
29
28
30
def takeWithUnfold (n : Int ): Stream [A ] =
29
31
unfold((this , n)) {
30
32
case (Cons (h, t), x) if x > 0 => Some ((h(), (t(), x - 1 )))
31
33
case _ => None
32
34
}
33
35
34
- def takeWhile (p : A => Boolean ): Stream [A ] = this match {
35
- case Cons (h, t) if p(h()) => cons(h(), t() takeWhile p)
36
- case _ => empty
37
- }
36
+ def takeWhile (p : A => Boolean ): Stream [A ] =
37
+ this match {
38
+ case Cons (h, t) if p(h()) => cons(h(), t() takeWhile p)
39
+ case _ => empty
40
+ }
38
41
39
42
def takeWhileWithUnfold (p : A => Boolean ): Stream [A ] =
40
43
unfold(this ) {
@@ -43,10 +46,11 @@ sealed trait Stream[+A] {
43
46
}
44
47
45
48
@ scala.annotation.tailrec
46
- final def drop (n : Int ): Stream [A ] = this match {
47
- case Cons (_, t) if n > 0 => t().drop(n - 1 )
48
- case _ => this
49
- }
49
+ final def drop (n : Int ): Stream [A ] =
50
+ this match {
51
+ case Cons (_, t) if n > 0 => t().drop(n - 1 )
52
+ case _ => this
53
+ }
50
54
51
55
// def exists2(p: A => Boolean): Boolean = this match {
52
56
// case Cons(h, t) => p(h()) || t().exists(p)
@@ -87,15 +91,17 @@ sealed trait Stream[+A] {
87
91
}
88
92
89
93
@ scala.annotation.tailrec
90
- final def foldLeft [B ](z : => B )(f : (=> B , A ) => B ): B = this match {
91
- case Empty => z
92
- case Cons (h, t) => t().foldLeft(f(z, h()))(f)
93
- }
94
+ final def foldLeft [B ](z : => B )(f : (=> B , A ) => B ): B =
95
+ this match {
96
+ case Empty => z
97
+ case Cons (h, t) => t().foldLeft(f(z, h()))(f)
98
+ }
94
99
95
- def foldRight [B ](z : => B )(f : (A , => B ) => B ): B = this match {
96
- case Cons (h, t) => f(h(), t().foldRight(z)(f))
97
- case _ => z
98
- }
100
+ def foldRight [B ](z : => B )(f : (A , => B ) => B ): B =
101
+ this match {
102
+ case Cons (h, t) => f(h(), t().foldRight(z)(f))
103
+ case _ => z
104
+ }
99
105
100
106
def takeWhile2 (p : A => Boolean ): Stream [A ] =
101
107
foldRight(empty[A ])((a, b) =>
@@ -162,6 +168,13 @@ sealed trait Stream[+A] {
162
168
163
169
def hasSubsequence [A ](s : Stream [A ]): Boolean =
164
170
tails exists (_ startsWith s)
171
+
172
+ def scanRight [B ](z : => B )(f : (A , => B ) => B ): Stream [B ] =
173
+ foldRight(cons(z, empty)) {
174
+ case (a, Cons (h, t)) => cons(f(a, h()), cons(h(), t()))
175
+ case _ => empty
176
+ // this case is impossible since we start the fold with cons(z, empty)
177
+ }
165
178
}
166
179
case object Empty extends Stream [Nothing ]
167
180
case class Cons [+ A ](h : () => A , t : () => Stream [A ]) extends Stream [A ]
@@ -213,7 +226,11 @@ object Stream {
213
226
def from (n : Int ): Stream [Int ] =
214
227
unfold(n)(s => Some ((s, s + 1 )))
215
228
216
- def constant [A ](a : A ): Stream [A ] =
217
- unfold(a)(s => Some ((s, s)))
229
+ def constant [A ](a : A ): Stream [A ] = {
230
+ lazy val stream : Stream [A ] = cons(a, stream)
231
+
232
+ stream
233
+ // unfold(a)(s => Some((s, s)))
234
+ }
218
235
219
236
}
0 commit comments