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