@@ -8,6 +8,11 @@ public protocol Show: ~Copyable {
8
8
borrowing func show( ) -> String
9
9
}
10
10
11
+ extension CustomStringConvertible {
12
+ public func show( ) -> String { return description }
13
+ }
14
+ extension Int : Show { }
15
+
11
16
public func print( _ s: borrowing some Show & ~ Copyable) {
12
17
print ( s. show ( ) )
13
18
}
@@ -54,33 +59,32 @@ public protocol Generator: ~Copyable {
54
59
public enum Pair < L: ~ Copyable, R: ~ Copyable> : ~ Copyable {
55
60
case elms( L , R )
56
61
}
62
+ extension Pair : Copyable where L: Copyable , R: Copyable { }
57
63
58
64
/// 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 )
62
67
case nothing
63
68
}
64
-
65
69
extension Maybe : Copyable { }
66
70
67
- extension Maybe : Show where Value : Show & ~ Copyable {
71
+ extension Maybe : Show where Wrapped : Show & ~ Copyable {
68
72
public borrowing func show( ) -> String {
69
73
switch self {
70
- case let . just( borrowing elm) :
74
+ case let . just( elm) :
71
75
return elm. show ( )
72
76
case . nothing:
73
77
return " <nothing> "
74
78
}
75
79
}
76
80
}
77
81
78
- extension Maybe : Eq where Value : Eq , Value : ~ Copyable {
82
+ extension Maybe : Eq where Wrapped : Eq , Wrapped : ~ Copyable {
79
83
public static func == ( _ a: borrowing Self , _ b: borrowing Self ) -> Bool {
80
84
switch a {
81
- case let . just( borrowing a1 ) :
85
+ case let . just( a1) :
82
86
switch b {
83
- case let . just( borrowing b1 ) :
87
+ case let . just( b1) :
84
88
return a1 == b1
85
89
case . nothing:
86
90
return false
@@ -96,19 +100,6 @@ extension Maybe: Eq where Value: Eq, Value: ~Copyable {
96
100
}
97
101
}
98
102
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
-
112
103
public func isJust< A: ~ Copyable> ( _ m: borrowing Maybe < A > ) -> Bool {
113
104
switch m {
114
105
case . just:
@@ -127,3 +118,144 @@ public struct UnownedRef<Instance: AnyObject> {
127
118
@usableFromInline
128
119
internal unowned(unsafe) var _value : Instance
129
120
}
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