1
+ package xcollections with
2
+ import annotation .unchecked .uncheckedVariance
3
+
4
+ abstract class LazyList [+ T ] with
5
+
6
+ private var myHead : T = _
7
+ private var myTail : LazyList [T ] = _
8
+ private var myForced : LazyList [T ] | Null = null
9
+
10
+ protected def force (): LazyList [T ]
11
+
12
+ protected def set (hd : T @ uncheckedVariance, tl : LazyList [T ] @ uncheckedVariance): LazyList [T ] =
13
+ assert(myForced == null , " implementation error: attempting to re-define existing LazyList" )
14
+ myHead = hd
15
+ myTail = tl
16
+ this
17
+
18
+ def forced (): LazyList [T ] =
19
+ var myForced = this .myForced
20
+ if myForced == null then
21
+ myForced = force()
22
+ this .myForced = myForced
23
+ assert(myForced.myForced != null , " implementation error: LazyList was not forced" )
24
+ myForced
25
+ else myForced
26
+
27
+ def isEmpty : Boolean = forced() eq LazyList .empty
28
+
29
+ def head : T =
30
+ val e = forced()
31
+ require(! e.isEmpty, " head on empty LazyList" )
32
+ e.myHead
33
+
34
+ def tail : LazyList [T ] =
35
+ val e = forced()
36
+ require(! e.isEmpty, " tail on empty LazyList" )
37
+ e.myTail
38
+
39
+ def fromIterable [T ](xs : Iterable [T ]) = xs match
40
+ case xs : LazyList [T ] @ unchecked => xs
41
+ case _ => LazyList .fromIterator(xs.iterator)
42
+
43
+ object LazyList with
44
+
45
+ val empty : LazyList [Nothing ] = new with
46
+ protected def force (): LazyList [Nothing ] = this
47
+
48
+ object #:: with
49
+ def unapply [T ](xs : LazyList [T ]): Option [(T , LazyList [T ])] =
50
+ if xs.isEmpty then None
51
+ else Some ((xs.head, xs.tail))
52
+
53
+ def fromIterator [T ](it : Iterator [T ]): LazyList [T ] = new with
54
+ protected def force () =
55
+ if it.hasNext then set(it.next, fromIterator (it))
56
+ else empty
57
+
58
+ given [T , U >: T ](xs : LazyList [T ]) extended with
59
+
60
+ def #:: (x : U ): LazyList [U ] = new with
61
+ protected def force (): LazyList [U ] =
62
+ set(x, xs)
63
+
64
+ def ++ (ys : LazyList [U ]): LazyList [U ] = new with
65
+ protected def force () =
66
+ if xs.isEmpty then ys.forced()
67
+ else set(xs.head, xs.tail ++ ys)
68
+
69
+ given [T , U ](xs : LazyList [T ]) extended with
70
+ def map (f : T => U ): LazyList [U ] = new with
71
+ protected def force () =
72
+ if xs.isEmpty then empty
73
+ else set(f(xs.head), xs.tail.map(f))
74
+
75
+ def flatMap (f : T => LazyList [U ]): LazyList [U ] = new with
76
+ protected def force (): LazyList [U ] =
77
+ if xs.isEmpty then empty
78
+ else f(xs.head) ++ xs.tail.flatMap(f)
79
+
80
+ def foldLeft (z : U )(f : (U , T ) => U ): U =
81
+ if xs.isEmpty then z
82
+ else xs.tail.foldLeft(f(z, xs.head))(f)
83
+
84
+ given [T ](xs : LazyList [T ]) extended with
85
+ def filter (p : T => Boolean ): LazyList [T ] = new with
86
+ protected def force (): LazyList [T ] =
87
+ if xs.isEmpty then empty
88
+ else if p(xs.head) then set(xs.head, xs.tail.filter(p))
89
+ else xs.tail.filter(p)
90
+
91
+ def take (n : Int ): LazyList [T ] =
92
+ if n <= 0 then empty
93
+ else new with
94
+ protected def force (): LazyList [T ] =
95
+ if xs.isEmpty then xs
96
+ else set(xs.head, xs.tail.take(n - 1 ))
97
+
98
+ def drop (n : Int ): LazyList [T ] =
99
+ if n <= 0 then xs
100
+ else new with
101
+ protected def force (): LazyList [T ] =
102
+ def advance (xs : LazyList [T ], n : Int ): LazyList [T ] =
103
+ if n <= 0 || xs.isEmpty then xs
104
+ else advance(xs.tail, n - 1 )
105
+ advance(xs, n)
106
+ end LazyList
107
+ end xcollections
108
+
109
+ @ main def Test () = ()
0 commit comments