@@ -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,66 +59,48 @@ 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
65
+ public typealias Maybe < Wrapped: ~ Copyable> = Optional < Wrapped >
59
66
60
- public enum Maybe < Value: ~ Copyable> : ~ Copyable {
61
- case just( Value )
62
- case nothing
63
- }
64
-
65
- extension Maybe : Copyable { }
66
-
67
- extension Maybe : Show where Value: Show & ~ Copyable {
67
+ extension Maybe : Show where Wrapped: Show & ~ Copyable {
68
68
public borrowing func show( ) -> String {
69
69
switch self {
70
- case let . just ( elm) :
70
+ case let . some ( elm) :
71
71
return elm. show ( )
72
- case . nothing :
72
+ case . none :
73
73
return " <nothing> "
74
74
}
75
75
}
76
76
}
77
77
78
- extension Maybe : Eq where Value : Eq , Value : ~ Copyable {
78
+ extension Maybe : Eq where Wrapped : Eq , Wrapped : ~ Copyable {
79
79
public static func == ( _ a: borrowing Self , _ b: borrowing Self ) -> Bool {
80
80
switch a {
81
- case let . just ( a1) :
81
+ case let . some ( a1) :
82
82
switch b {
83
- case let . just ( b1) :
83
+ case let . some ( b1) :
84
84
return a1 == b1
85
- case . nothing :
85
+ case . none :
86
86
return false
87
87
}
88
- case . nothing :
88
+ case . none :
89
89
switch b {
90
- case . just :
90
+ case . some :
91
91
return false
92
- case . nothing :
92
+ case . none :
93
93
return true
94
94
}
95
95
}
96
96
}
97
97
}
98
98
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
99
public func isJust< A: ~ Copyable> ( _ m: borrowing Maybe < A > ) -> Bool {
113
100
switch m {
114
- case . just :
101
+ case . some :
115
102
return true
116
- case . nothing :
103
+ case . none :
117
104
return false
118
105
}
119
106
}
@@ -127,3 +114,144 @@ public struct UnownedRef<Instance: AnyObject> {
127
114
@usableFromInline
128
115
internal unowned(unsafe) var _value : Instance
129
116
}
117
+
118
+ /// Provides underlying support so that you can create recursive enums, because
119
+ /// noncopyable enums do not yet support indirect cases.
120
+ public struct Box < Wrapped: ~ Copyable> : ~ Copyable {
121
+ private let _pointer : UnsafeMutablePointer < Wrapped >
122
+
123
+ init ( _ wrapped: consuming Wrapped ) {
124
+ _pointer = . allocate( capacity: 1 )
125
+ _pointer. initialize ( to: wrapped)
126
+ }
127
+
128
+ deinit {
129
+ _pointer. deinitialize ( count: 1 )
130
+ _pointer. deallocate ( )
131
+ }
132
+
133
+ consuming func take( ) -> Wrapped {
134
+ let wrapped = _pointer. move ( )
135
+ _pointer. deallocate ( )
136
+ discard self
137
+ return wrapped
138
+ }
139
+
140
+ var borrow : Wrapped {
141
+ _read { yield _pointer. pointee }
142
+ }
143
+
144
+ consuming func map( _ transform: ( consuming Wrapped ) -> Wrapped ) -> Self {
145
+ _pointer. initialize ( to: transform ( _pointer. move ( ) ) )
146
+ return self
147
+ }
148
+ }
149
+
150
+
151
+ /// MARK: Data.List
152
+ public enum List < Element: ~ Copyable> : ~ Copyable {
153
+ case cons( Element , Box < List < Element > > )
154
+ case empty
155
+
156
+ public init ( _ head: consuming Element ,
157
+ _ tail: consuming List < Element > ) {
158
+ self = . cons( head, Box ( tail) )
159
+ }
160
+
161
+ public init ( ) { self = . empty }
162
+ }
163
+
164
+ /// Pure Iteration
165
+ extension List where Element: ~ Copyable {
166
+ /// Performs forward iteration through the list, accumulating a result value.
167
+ /// Returns f(xn,...,f(x2, f(x1, init))...), or init if the list is empty.
168
+ public borrowing func foldl< Out> (
169
+ init initial: consuming Out ,
170
+ _ f: ( borrowing Element , consuming Out ) -> Out ) -> Out
171
+ where Out: ~ Copyable {
172
+ func loop( _ acc: consuming Out , _ lst: borrowing Self ) -> Out {
173
+ switch lst {
174
+ case . empty:
175
+ return acc
176
+ case let . cons( elm, tail) :
177
+ return loop ( f ( elm, acc) , tail. borrow)
178
+ }
179
+ }
180
+ return loop ( initial, self )
181
+ }
182
+
183
+ /// Performs reverse iteration through the list, accumulating a result value.
184
+ /// Returns f(x1, f(x2,...,f(xn, init)...)) or init if the list is empty.
185
+ public borrowing func foldr< Out> (
186
+ init initial: consuming Out ,
187
+ _ f: ( borrowing Element , consuming Out ) -> Out ) -> Out
188
+ where Out: ~ Copyable {
189
+ switch self {
190
+ case . empty:
191
+ return initial
192
+ case let . cons( elm, tail) :
193
+ return f ( elm, tail. borrow. foldr ( init: initial, f) )
194
+ }
195
+ }
196
+
197
+ // Forward iteration without accumulating a result.
198
+ public borrowing func forEach( _ f: ( borrowing Element ) -> Void ) -> Void {
199
+ switch self {
200
+ case . empty: return
201
+ case let . cons( elm, tail) :
202
+ f ( elm)
203
+ return tail. borrow. forEach ( f)
204
+ }
205
+ }
206
+ }
207
+
208
+ /// Initialization
209
+ extension List where Element: ~ Copyable {
210
+ // Generates a list of elements [f(0), f(1), ..., f(n-1)] from left to right.
211
+ // For n < 0, the empty list is created.
212
+ public init ( length n: Int , _ f: ( Int ) -> Element ) {
213
+ guard n > 0 else {
214
+ self = . empty
215
+ return
216
+ }
217
+
218
+ let cur = n- 1
219
+ let elm = f ( cur)
220
+ self = List ( elm, List ( length: cur, f) )
221
+ }
222
+ }
223
+
224
+ /// Basic utilities
225
+ extension List where Element: ~ Copyable {
226
+ /// Is this list empty?
227
+ public borrowing func empty( ) -> Bool {
228
+ switch self {
229
+ case . empty: return true
230
+ case . cons( _, _) : return false
231
+ }
232
+ }
233
+
234
+ /// How many elements are in this list?
235
+ public borrowing func length( ) -> Int {
236
+ return foldl ( init: 0 ) { $1 + 1 }
237
+ }
238
+
239
+ /// Pop the first element off the list, if present.
240
+ public consuming func pop( ) -> Maybe < Pair < Element , List < Element > > > {
241
+ switch consume self {
242
+ case . empty: . none
243
+ case let . cons( elm, tail) : . elms( elm, tail. take ( ) )
244
+ }
245
+ }
246
+
247
+ /// Push an element onto the list.
248
+ public consuming func push( _ newHead: consuming Element ) -> List < Element > {
249
+ return List ( newHead, self )
250
+ }
251
+ }
252
+
253
+ extension List : Show where Element: Show & ~ Copyable {
254
+ public borrowing func show( ) -> String {
255
+ return " [ " + foldl( init: " ] " , { $0. show ( ) + " , " + $1 } )
256
+ }
257
+ }
0 commit comments