@@ -8,6 +8,11 @@ public protocol Show: ~Copyable {
88 borrowing func show( ) -> String
99}
1010
11+ extension CustomStringConvertible {
12+ public func show( ) -> String { return description }
13+ }
14+ extension Int : Show { }
15+
1116public func print( _ s: borrowing some Show & ~ Copyable) {
1217 print ( s. show ( ) )
1318}
@@ -54,33 +59,32 @@ public protocol Generator: ~Copyable {
5459public enum Pair < L: ~ Copyable, R: ~ Copyable> : ~ Copyable {
5560 case elms( L , R )
5661}
62+ extension Pair : Copyable where L: Copyable , R: Copyable { }
5763
5864/// MARK: Data.Maybe
59-
60- public enum Maybe < Value: ~ Copyable> : ~ Copyable {
61- case just( Value )
65+ public enum Maybe < Wrapped: ~ Copyable> : ~ Copyable {
66+ case just( Wrapped )
6267 case nothing
6368}
64-
6569extension Maybe : Copyable { }
6670
67- extension Maybe : Show where Value : Show & ~ Copyable {
71+ extension Maybe : Show where Wrapped : Show & ~ Copyable {
6872 public borrowing func show( ) -> String {
6973 switch self {
70- case let . just( borrowing elm) :
74+ case let . just( elm) :
7175 return elm. show ( )
7276 case . nothing:
7377 return " <nothing> "
7478 }
7579 }
7680}
7781
78- extension Maybe : Eq where Value : Eq , Value : ~ Copyable {
82+ extension Maybe : Eq where Wrapped : Eq , Wrapped : ~ Copyable {
7983 public static func == ( _ a: borrowing Self , _ b: borrowing Self ) -> Bool {
8084 switch a {
81- case let . just( borrowing a1 ) :
85+ case let . just( a1) :
8286 switch b {
83- case let . just( borrowing b1 ) :
87+ case let . just( b1) :
8488 return a1 == b1
8589 case . nothing:
8690 return false
@@ -96,19 +100,6 @@ extension Maybe: Eq where Value: Eq, Value: ~Copyable {
96100 }
97101}
98102
99-
100- // FIXME: triggers crash!
101- // @inlinable
102- // public func fromMaybe<A: ~Copyable>(_ defaultVal: consuming A,
103- // _ mayb: consuming Maybe<A>) -> A {
104- // switch mayb {
105- // case let .just(payload):
106- // return payload
107- // case .nothing:
108- // return defaultVal
109- // }
110- // }
111-
112103public func isJust< A: ~ Copyable> ( _ m: borrowing Maybe < A > ) -> Bool {
113104 switch m {
114105 case . just:
@@ -127,3 +118,144 @@ public struct UnownedRef<Instance: AnyObject> {
127118 @usableFromInline
128119 internal unowned(unsafe) var _value : Instance
129120}
121+
122+ /// Provides underlying support so that you can create recursive enums, because
123+ /// noncopyable enums do not yet support indirect cases.
124+ public struct Box < Wrapped: ~ Copyable> : ~ Copyable {
125+ private let _pointer : UnsafeMutablePointer < Wrapped >
126+
127+ init ( _ wrapped: consuming Wrapped ) {
128+ _pointer = . allocate( capacity: 1 )
129+ _pointer. initialize ( to: wrapped)
130+ }
131+
132+ deinit {
133+ _pointer. deinitialize ( count: 1 )
134+ _pointer. deallocate ( )
135+ }
136+
137+ consuming func take( ) -> Wrapped {
138+ let wrapped = _pointer. move ( )
139+ _pointer. deallocate ( )
140+ discard self
141+ return wrapped
142+ }
143+
144+ var borrow : Wrapped {
145+ _read { yield _pointer. pointee }
146+ }
147+
148+ consuming func map( _ transform: ( consuming Wrapped ) -> Wrapped ) -> Self {
149+ _pointer. initialize ( to: transform ( _pointer. move ( ) ) )
150+ return self
151+ }
152+ }
153+
154+
155+ /// MARK: Data.List
156+ public enum List < Element: ~ Copyable> : ~ Copyable {
157+ case cons( Element , Box < List < Element > > )
158+ case empty
159+
160+ public init ( _ head: consuming Element ,
161+ _ tail: consuming List < Element > ) {
162+ self = . cons( head, Box ( tail) )
163+ }
164+
165+ public init ( ) { self = . empty }
166+ }
167+
168+ /// Pure Iteration
169+ extension List where Element: ~ Copyable {
170+ /// Performs forward iteration through the list, accumulating a result value.
171+ /// Returns f(xn,...,f(x2, f(x1, init))...), or init if the list is empty.
172+ public borrowing func foldl< Out> (
173+ init initial: consuming Out ,
174+ _ f: ( borrowing Element , consuming Out ) -> Out ) -> Out
175+ where Out: ~ Copyable {
176+ func loop( _ acc: consuming Out , _ lst: borrowing Self ) -> Out {
177+ switch lst {
178+ case . empty:
179+ return acc
180+ case let . cons( elm, tail) :
181+ return loop ( f ( elm, acc) , tail. borrow)
182+ }
183+ }
184+ return loop ( initial, self )
185+ }
186+
187+ /// Performs reverse iteration through the list, accumulating a result value.
188+ /// Returns f(x1, f(x2,...,f(xn, init)...)) or init if the list is empty.
189+ public borrowing func foldr< Out> (
190+ init initial: consuming Out ,
191+ _ f: ( borrowing Element , consuming Out ) -> Out ) -> Out
192+ where Out: ~ Copyable {
193+ switch self {
194+ case . empty:
195+ return initial
196+ case let . cons( elm, tail) :
197+ return f ( elm, tail. borrow. foldr ( init: initial, f) )
198+ }
199+ }
200+
201+ // Forward iteration without accumulating a result.
202+ public borrowing func forEach( _ f: ( borrowing Element ) -> Void ) -> Void {
203+ switch self {
204+ case . empty: return
205+ case let . cons( elm, tail) :
206+ f ( elm)
207+ return tail. borrow. forEach ( f)
208+ }
209+ }
210+ }
211+
212+ /// Initialization
213+ extension List where Element: ~ Copyable {
214+ // Generates a list of elements [f(0), f(1), ..., f(n-1)] from left to right.
215+ // For n < 0, the empty list is created.
216+ public init ( length n: Int , _ f: ( Int ) -> Element ) {
217+ guard n > 0 else {
218+ self = . empty
219+ return
220+ }
221+
222+ let cur = n- 1
223+ let elm = f ( cur)
224+ self = List ( elm, List ( length: cur, f) )
225+ }
226+ }
227+
228+ /// Basic utilities
229+ extension List where Element: ~ Copyable {
230+ /// Is this list empty?
231+ public borrowing func empty( ) -> Bool {
232+ switch self {
233+ case . empty: return true
234+ case . cons( _, _) : return false
235+ }
236+ }
237+
238+ /// How many elements are in this list?
239+ public borrowing func length( ) -> Int {
240+ return foldl ( init: 0 ) { $1 + 1 }
241+ }
242+
243+ /// Pop the first element off the list, if present.
244+ public consuming func pop( ) -> Optional < Pair < Element , List < Element > > > {
245+ switch consume self {
246+ case . empty: . none
247+ case let . cons( elm, tail) : . elms( elm, tail. take ( ) )
248+ }
249+ }
250+
251+ /// Push an element onto the list.
252+ public consuming func push( _ newHead: consuming Element ) -> List < Element > {
253+ return List ( newHead, self )
254+ }
255+ }
256+
257+ extension List : Show where Element: Show & ~ Copyable {
258+ public borrowing func show( ) -> String {
259+ return " [ " + foldl( init: " ] " , { $0. show ( ) + " , " + $1 } )
260+ }
261+ }
0 commit comments