@effekt-lang/effekt 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,32 +4,32 @@ import effekt
4
4
  import option
5
5
  import exception
6
6
 
7
- // Immutable linked list for finite sequences of elements.
7
+ /// Immutable linked list for finite sequences of elements.
8
8
  type List[A] {
9
9
  Nil();
10
10
  Cons(head: A, tail: List[A])
11
11
  }
12
12
 
13
- // Create an empty list.
14
- //
15
- // O(1)
13
+ /// Create an empty list.
14
+ ///
15
+ /// O(1)
16
16
  def empty[A](): List[A] = Nil()
17
17
 
18
- // Create a list with one element.
19
- //
20
- // O(1)
18
+ /// Create a list with one element.
19
+ ///
20
+ /// O(1)
21
21
  def singleton[A](x: A): List[A] = Cons(x, Nil())
22
22
 
23
- // Create a list of length `size` where all elements are `default`.
24
- //
25
- // O(size)
23
+ /// Create a list of length `size` where all elements are `default`.
24
+ ///
25
+ /// O(size)
26
26
  def fill[A](size: Int, default: A): List[A] = {
27
27
  build(size) { i => default }
28
28
  }
29
29
 
30
- // Create a list from a function `index` of given `size`.
31
- //
32
- // O(size)
30
+ /// Create a list from a function `index` of given `size`.
31
+ ///
32
+ /// O(size)
33
33
  def build[A](size: Int) { index: Int => A }: List[A] = {
34
34
  var result = empty()
35
35
  each(0, size) { i =>
@@ -38,52 +38,52 @@ def build[A](size: Int) { index: Int => A }: List[A] = {
38
38
  result.reverse
39
39
  }
40
40
 
41
- // Check if list is empty.
42
- //
43
- // O(1)
41
+ /// Check if list is empty.
42
+ ///
43
+ /// O(1)
44
44
  def isEmpty[A](l: List[A]): Bool = l match {
45
45
  case Nil() => true
46
46
  case Cons(a, rest) => false
47
47
  }
48
48
 
49
- // Check if list is nonempty.
50
- //
51
- // O(1)
49
+ /// Check if list is nonempty.
50
+ ///
51
+ /// O(1)
52
52
  def nonEmpty[A](l: List[A]): Bool = l match {
53
53
  case Nil() => false
54
54
  case Cons(a, rest) => true
55
55
  }
56
56
 
57
- // Return the first element of a given list.
58
- // Throws a `MissingValue` exception if it's empty.
59
- //
60
- // O(1)
57
+ /// Return the first element of a given list.
58
+ /// Throws a `MissingValue` exception if it's empty.
59
+ ///
60
+ /// O(1)
61
61
  def head[A](l: List[A]): A / Exception[MissingValue] = l match {
62
62
  case Nil() => do raise(MissingValue(), "Trying to get the head of an empty list")
63
63
  case Cons(a, rest) => a
64
64
  }
65
65
 
66
- // Return all elements of a given list except the first element.
67
- // Throws a `MissingValue` exception if it's empty.
68
- //
69
- // O(1)
66
+ /// Return all elements of a given list except the first element.
67
+ /// Throws a `MissingValue` exception if it's empty.
68
+ ///
69
+ /// O(1)
70
70
  def tail[A](l: List[A]): List[A] / Exception[MissingValue] = l match {
71
71
  case Nil() => do raise(MissingValue(), "Trying to get the head of an empty list")
72
72
  case Cons(a, rest) => rest
73
73
  }
74
74
 
75
- // Return the first element of a given list.
76
- // Returns `None()` if it's empty.
77
- //
78
- // O(1)
75
+ /// Return the first element of a given list.
76
+ /// Returns `None()` if it's empty.
77
+ ///
78
+ /// O(1)
79
79
  def headOption[A](l: List[A]): Option[A] = l match {
80
80
  case Nil() => None()
81
81
  case Cons(a, rest) => Some(a)
82
82
  }
83
83
 
84
- // Returns the last element of a given list.
85
- //
86
- // O(N)
84
+ /// Returns the last element of a given list.
85
+ ///
86
+ /// O(N)
87
87
  def last[A](l: List[A]): A / Exception[MissingValue] = {
88
88
  def go(list: List[A]): A = {
89
89
  list match {
@@ -96,9 +96,9 @@ def last[A](l: List[A]): A / Exception[MissingValue] = {
96
96
  go(l)
97
97
  }
98
98
 
99
- // Get the value at given index.
100
- //
101
- // O(N)
99
+ /// Get the value at given index.
100
+ ///
101
+ /// O(N)
102
102
  def get[A](list: List[A], index: Int): A / Exception[OutOfBounds] = {
103
103
  def go(list: List[A], i: Int): A = {
104
104
  list match {
@@ -111,17 +111,17 @@ def get[A](list: List[A], index: Int): A / Exception[OutOfBounds] = {
111
111
  go(list, index)
112
112
  }
113
113
 
114
- // Traverse a list, applying the given action on every element.
115
- //
116
- // O(N)
114
+ /// Traverse a list, applying the given action on every element.
115
+ ///
116
+ /// O(N)
117
117
  def foreach[A](l: List[A]) { f: (A) => Unit } : Unit = l match {
118
118
  case Nil() => ()
119
119
  case Cons(head, tail) => f(head); tail.foreach {f}
120
120
  }
121
121
 
122
- // Traverse a list, applying the given action on every element.
123
- //
124
- // O(N)
122
+ /// Traverse a list, applying the given action on every element.
123
+ ///
124
+ /// O(N)
125
125
  def foreach[A](l: List[A]) { f: (A) {Control} => Unit } : Unit = {
126
126
  var remainder = l
127
127
  loop { {label} =>
@@ -134,9 +134,9 @@ def foreach[A](l: List[A]) { f: (A) {Control} => Unit } : Unit = {
134
134
  }
135
135
  }
136
136
 
137
- // Traverse a list, applying the given action on every element and its (zero-based) index.
138
- //
139
- // O(N)
137
+ /// Traverse a list, applying the given action on every element and its (zero-based) index.
138
+ ///
139
+ /// O(N)
140
140
  def foreachIndex[A](list: List[A]){ f: (Int, A) => Unit }: Unit = {
141
141
  def loop(index: Int, remainder: List[A]): Unit = remainder match {
142
142
  case Nil() => ()
@@ -147,9 +147,9 @@ def foreachIndex[A](list: List[A]){ f: (Int, A) => Unit }: Unit = {
147
147
  loop(0, list)
148
148
  }
149
149
 
150
- // Traverse a list, applying the given action on every element and its (zero-based) index.
151
- //
152
- // O(N)
150
+ /// Traverse a list, applying the given action on every element and its (zero-based) index.
151
+ ///
152
+ /// O(N)
153
153
  def foreachIndex[A](list: List[A]){ f: (Int, A) {Control} => Unit }: Unit = {
154
154
  var remainder = list
155
155
  var i = -1
@@ -164,20 +164,20 @@ def foreachIndex[A](list: List[A]){ f: (Int, A) {Control} => Unit }: Unit = {
164
164
  }
165
165
  }
166
166
 
167
- // Map a function `f` over elements in a given list.
168
- //
169
- // O(N)
167
+ /// Map a function `f` over elements in a given list.
168
+ ///
169
+ /// O(N)
170
170
  def map[A, B](l: List[A]) { f: A => B } : List[B] = {
171
171
  var acc = Nil[B]()
172
172
  l.foreach { el => acc = Cons(f(el), acc) }
173
173
  acc.reverse
174
174
  }
175
175
 
176
- // Map a function `f` over elements in a given list,
177
- // keeping only the elements for which the function returned `Some(...)`,
178
- // discarding the elements for which the function returned `None()`.
179
- //
180
- // O(N)
176
+ /// Map a function `f` over elements in a given list,
177
+ /// keeping only the elements for which the function returned `Some(...)`,
178
+ /// discarding the elements for which the function returned `None()`.
179
+ ///
180
+ /// O(N)
181
181
  def collect[A, B](l: List[A]) { f : A => Option[B] }: List[B] = {
182
182
  var acc = Nil[B]()
183
183
  l.foreach { a =>
@@ -190,9 +190,9 @@ def collect[A, B](l: List[A]) { f : A => Option[B] }: List[B] = {
190
190
  acc.reverse
191
191
  }
192
192
 
193
- // Map a function `f` over elements in a given list and concatenate the results.
194
- //
195
- // O(N)
193
+ /// Map a function `f` over elements in a given list and concatenate the results.
194
+ ///
195
+ /// O(N)
196
196
  def flatMap[A, B](l: List[A]) { f : A => List[B] }: List[B] = {
197
197
  var acc = Nil[B]()
198
198
  l.foreach { a =>
@@ -202,9 +202,9 @@ def flatMap[A, B](l: List[A]) { f : A => List[B] }: List[B] = {
202
202
  acc
203
203
  }
204
204
 
205
- // Check if predicate is true for all elements of the given list.
206
- //
207
- // O(N)
205
+ /// Check if predicate is true for all elements of the given list.
206
+ ///
207
+ /// O(N)
208
208
  def all[A](list: List[A]) { predicate: A => Bool }: Bool = {
209
209
  list match {
210
210
  case Cons(x, xs) => predicate(x) && all(xs) { predicate }
@@ -212,9 +212,9 @@ def all[A](list: List[A]) { predicate: A => Bool }: Bool = {
212
212
  }
213
213
  }
214
214
 
215
- // Check if predicate is true for at least one element of the given list.
216
- //
217
- // O(N)
215
+ /// Check if predicate is true for at least one element of the given list.
216
+ ///
217
+ /// O(N)
218
218
  def any[A](list: List[A]) { predicate: A => Bool }: Bool = {
219
219
  list match {
220
220
  case Cons(x, xs) => predicate(x) || any(xs) { predicate }
@@ -222,89 +222,89 @@ def any[A](list: List[A]) { predicate: A => Bool }: Bool = {
222
222
  }
223
223
  }
224
224
 
225
- // Fold a list using `f`, starting from the left given a starting value.
226
- //
227
- // O(N)
225
+ /// Fold a list using `f`, starting from the left given a starting value.
226
+ ///
227
+ /// O(N)
228
228
  def foldLeft[A, B](l: List[A], init: B) { f: (B, A) => B }: B = {
229
229
  var acc = init;
230
230
  l.foreach { x => acc = f(acc, x) };
231
231
  acc
232
232
  }
233
233
 
234
- // Fold a list using `f`, starting from the right given a starting value.
235
- //
236
- // O(N)
234
+ /// Fold a list using `f`, starting from the right given a starting value.
235
+ ///
236
+ /// O(N)
237
237
  def foldRight[A, B](l: List[A], init: B) { f: (A, B) => B }: B = {
238
238
  var acc = init;
239
239
  l.reverse.foreach { x => acc = f(x, acc) };
240
240
  acc
241
241
  }
242
242
 
243
- // Sum the elements of the list.
244
- //
245
- // O(N)
243
+ /// Sum the elements of the list.
244
+ ///
245
+ /// O(N)
246
246
  def sum(list: List[Int]): Int = {
247
247
  var n = 0;
248
248
  list.foreach { x => n = n + x };
249
249
  n
250
250
  }
251
251
 
252
- // Calculate the size of the list.
253
- //
254
- // O(N)
252
+ /// Calculate the size of the list.
253
+ ///
254
+ /// O(N)
255
255
  def size[A](l: List[A]): Int = {
256
256
  var n = 0;
257
257
  l.foreach { _ => n = n + 1 };
258
258
  n
259
259
  }
260
260
 
261
- // Reverse the list.
262
- //
263
- // O(N)
261
+ /// Reverse the list.
262
+ ///
263
+ /// O(N)
264
264
  def reverse[A](l: List[A]): List[A] = {
265
265
  var res = Nil[A]()
266
266
  l.foreach { el => res = Cons(el, res) }
267
267
  res
268
268
  }
269
269
 
270
- // Reverse a list `l` and append `other` to it.
271
- //
272
- // Example:
273
- // ```
274
- // > [1,2,3].reverseOnto([4,5,6])
275
- // [3,2,1,4,5,6]
276
- // ```
277
- //
278
- // O(|l|)
270
+ /// Reverse a list `l` and append `other` to it.
271
+ ///
272
+ /// Example:
273
+ /// ```
274
+ /// > [1,2,3].reverseOnto([4,5,6])
275
+ /// [3,2,1,4,5,6]
276
+ /// ```
277
+ ///
278
+ /// O(|l|)
279
279
  def reverseOnto[A](l: List[A], other: List[A]): List[A] = l match {
280
280
  case Nil() => other
281
281
  case Cons(a, rest) => rest.reverseOnto(Cons(a, other))
282
282
  }
283
283
 
284
- // Concatenate list `l` with list `other`:
285
- //
286
- // Example:
287
- // ```
288
- // > [1,2,3].append([4,5,6])
289
- // [1,2,3,4,5,6]
290
- // ```
291
- //
292
- // O(N)
284
+ /// Concatenate list `l` with list `other`:
285
+ ///
286
+ /// Example:
287
+ /// ```
288
+ /// > [1,2,3].append([4,5,6])
289
+ /// [1,2,3,4,5,6]
290
+ /// ```
291
+ ///
292
+ /// O(N)
293
293
  def append[A](l: List[A], other: List[A]): List[A] =
294
294
  l.reverse.reverseOnto(other)
295
295
 
296
- // Flatten a list of lists into a single list.
297
- //
298
- // Examples:
299
- // ```
300
- // > [[1, 2, 3], [4, 5], [6]].join()
301
- // [1, 2, 3, 4, 5, 6]
302
- //
303
- // > [[]].join()
304
- // []
305
- // ```
306
- //
307
- // O(N)
296
+ /// Flatten a list of lists into a single list.
297
+ ///
298
+ /// Examples:
299
+ /// ```
300
+ /// > [[1, 2, 3], [4, 5], [6]].join()
301
+ /// [1, 2, 3, 4, 5, 6]
302
+ ///
303
+ /// > [[]].join()
304
+ /// []
305
+ /// ```
306
+ ///
307
+ /// O(N)
308
308
  def join[A](lists: List[List[A]]): List[A] = {
309
309
  var acc: List[A] = Nil()
310
310
  lists.foreach { list =>
@@ -313,19 +313,19 @@ def join[A](lists: List[List[A]]): List[A] = {
313
313
  acc
314
314
  }
315
315
 
316
- // Flatten a list of lists into a single list,
317
- // putting the `between` list in between each list in the input.
318
- //
319
- // Examples:
320
- // ```
321
- // > [[100], [200, 300], [400]].join([1, 2, 3])
322
- // [100, 1, 2, 3, 200, 300, 1, 2, 3, 400]
323
- //
324
- // > [[]].join([1, 2, 3])
325
- // []
326
- // ```
327
- //
328
- // O(N)
316
+ /// Flatten a list of lists into a single list,
317
+ /// putting the `between` list in between each list in the input.
318
+ ///
319
+ /// Examples:
320
+ /// ```
321
+ /// > [[100], [200, 300], [400]].join([1, 2, 3])
322
+ /// [100, 1, 2, 3, 200, 300, 1, 2, 3, 400]
323
+ ///
324
+ /// > [[]].join([1, 2, 3])
325
+ /// []
326
+ /// ```
327
+ ///
328
+ /// O(N)
329
329
  def join[A](lists: List[List[A]], between: List[A]): List[A] = {
330
330
  lists match {
331
331
  case Nil() => Nil()
@@ -336,27 +336,27 @@ def join[A](lists: List[List[A]], between: List[A]): List[A] = {
336
336
  }
337
337
  }
338
338
 
339
- // Take the first `n` elements of a given list.
340
- //
341
- // Examples:
342
- // ```
343
- // > [1, 2, 3].take(2)
344
- // [1, 2]
345
- //
346
- // > [1, 2, 3].take(0)
347
- // []
348
- //
349
- // > [1, 2, 3].take(3)
350
- // [1, 2, 3]
351
- //
352
- // > [1, 2, 3].take(5)
353
- // [1, 2, 3]
354
- //
355
- // > [1, 2, 3].take(-1)
356
- // []
357
- // ```
358
- //
359
- // O(n)
339
+ /// Take the first `n` elements of a given list.
340
+ ///
341
+ /// Examples:
342
+ /// ```
343
+ /// > [1, 2, 3].take(2)
344
+ /// [1, 2]
345
+ ///
346
+ /// > [1, 2, 3].take(0)
347
+ /// []
348
+ ///
349
+ /// > [1, 2, 3].take(3)
350
+ /// [1, 2, 3]
351
+ ///
352
+ /// > [1, 2, 3].take(5)
353
+ /// [1, 2, 3]
354
+ ///
355
+ /// > [1, 2, 3].take(-1)
356
+ /// []
357
+ /// ```
358
+ ///
359
+ /// O(n)
360
360
  def take[A](l: List[A], n: Int): List[A] =
361
361
  if (n <= 0) {
362
362
  Nil()
@@ -365,27 +365,27 @@ def take[A](l: List[A], n: Int): List[A] =
365
365
  case Cons(a, rest) => Cons(a, rest.take(n - 1))
366
366
  }
367
367
 
368
- // Drop the first `n` elements of a given list.
369
- //
370
- // Examples:
371
- // ```
372
- // > [1, 2, 3].drop(2)
373
- // [3]
374
- //
375
- // > [1, 2, 3].drop(0)
376
- // [1, 2, 3]
377
- //
378
- // > [1, 2, 3].drop(3)
379
- // []
380
- //
381
- // > [1, 2, 3].drop(5)
382
- // []
383
- //
384
- // > [1, 2, 3].drop(-1)
385
- // [1, 2, 3]
386
- // ```
387
- //
388
- // O(n)
368
+ /// Drop the first `n` elements of a given list.
369
+ ///
370
+ /// Examples:
371
+ /// ```
372
+ /// > [1, 2, 3].drop(2)
373
+ /// [3]
374
+ ///
375
+ /// > [1, 2, 3].drop(0)
376
+ /// [1, 2, 3]
377
+ ///
378
+ /// > [1, 2, 3].drop(3)
379
+ /// []
380
+ ///
381
+ /// > [1, 2, 3].drop(5)
382
+ /// []
383
+ ///
384
+ /// > [1, 2, 3].drop(-1)
385
+ /// [1, 2, 3]
386
+ /// ```
387
+ ///
388
+ /// O(n)
389
389
  def drop[A](l: List[A], n: Int): List[A] =
390
390
  if (n <= 0) {
391
391
  l
@@ -394,57 +394,57 @@ def drop[A](l: List[A], n: Int): List[A] =
394
394
  case Cons(a, rest) => rest.drop(n - 1)
395
395
  }
396
396
 
397
- // Return a slice of a given list from the starting index (inclusive)
398
- // to the given end index (exclusive).
399
- //
400
- // Examples:
401
- // ```
402
- // > [1, 2, 3, 4, 5, 6].slice(1, 4)
403
- // [2, 3, 4]
404
- //
405
- // > [1, 2, 3, 4, 5, 6].slice(1, 2)
406
- // [2]
407
- //
408
- // > [1, 2, 3, 4, 5, 6].slice(1, 1)
409
- // []
410
- //
411
- // > [1, 2, 3, 4, 5, 6].slice(4, 1)
412
- // []
413
- //
414
- // > [1, 2, 3, 4, 5, 6].slice(-100, 100)
415
- // [1, 2, 3, 4, 5, 6]
416
- // ```
417
- //
418
- // O(N)
397
+ /// Return a slice of a given list from the starting index (inclusive)
398
+ /// to the given end index (exclusive).
399
+ ///
400
+ /// Examples:
401
+ /// ```
402
+ /// > [1, 2, 3, 4, 5, 6].slice(1, 4)
403
+ /// [2, 3, 4]
404
+ ///
405
+ /// > [1, 2, 3, 4, 5, 6].slice(1, 2)
406
+ /// [2]
407
+ ///
408
+ /// > [1, 2, 3, 4, 5, 6].slice(1, 1)
409
+ /// []
410
+ ///
411
+ /// > [1, 2, 3, 4, 5, 6].slice(4, 1)
412
+ /// []
413
+ ///
414
+ /// > [1, 2, 3, 4, 5, 6].slice(-100, 100)
415
+ /// [1, 2, 3, 4, 5, 6]
416
+ /// ```
417
+ ///
418
+ /// O(N)
419
419
  def slice[A](list: List[A], start: Int, stopExclusive: Int): List[A] = {
420
420
  val prefix = list.drop(start)
421
421
  val length = stopExclusive - start
422
422
  prefix.take(length)
423
423
  }
424
424
 
425
- // Split the list at given index.
426
- //
427
- // Law: `val (l, r) = list.splitAt(i); l.append(r) === list`
428
- //
429
- // O(N)
425
+ /// Split the list at given index.
426
+ ///
427
+ /// Law: `val (l, r) = list.splitAt(i); l.append(r) === list`
428
+ ///
429
+ /// O(N)
430
430
  def splitAt[A](list: List[A], index: Int): (List[A], List[A]) = {
431
431
  (list.take(index), list.drop(index))
432
432
  }
433
433
 
434
- // Update the element at given index in the list using the `update` function.
435
- // Returns the original list if the index is out of bounds.
436
- //
437
- // See: `modifyAt`
438
- // Examples:
439
- // ```
440
- // > [1, 2, 3].updateAt(1) { n => n + 100 }
441
- // [1, 102, 3]
442
- //
443
- // > [1, 2, 3].updateAt(10) { n => n + 100 }
444
- // [1, 2, 3]
445
- // ```
446
- //
447
- // O(N)
434
+ /// Update the element at given index in the list using the `update` function.
435
+ /// Returns the original list if the index is out of bounds.
436
+ ///
437
+ /// See: `modifyAt`
438
+ /// Examples:
439
+ /// ```
440
+ /// > [1, 2, 3].updateAt(1) { n => n + 100 }
441
+ /// [1, 102, 3]
442
+ ///
443
+ /// > [1, 2, 3].updateAt(10) { n => n + 100 }
444
+ /// [1, 2, 3]
445
+ /// ```
446
+ ///
447
+ /// O(N)
448
448
  def updateAt[A](list: List[A], index: Int) { update: A => A }: List[A] = {
449
449
  list.splitAt(index) match {
450
450
  case (left, Cons(x, right)) =>
@@ -453,20 +453,20 @@ def updateAt[A](list: List[A], index: Int) { update: A => A }: List[A] = {
453
453
  }
454
454
  }
455
455
 
456
- // Modify the element at given index in the list using the `update` function.
457
- // Throws `OutOfBounds` if the index is out of bounds.
458
- //
459
- // See: `updateAt`
460
- // Examples:
461
- // ```
462
- // > [1, 2, 3].modifyAt(1) { n => n + 100 }
463
- // Some([1, 102, 3])
464
- //
465
- // > [1, 2, 3].modifyAt(10) { n => n + 100 }
466
- // None()
467
- // ```
468
- //
469
- // O(N)
456
+ /// Modify the element at given index in the list using the `update` function.
457
+ /// Throws `OutOfBounds` if the index is out of bounds.
458
+ ///
459
+ /// See: `updateAt`
460
+ /// Examples:
461
+ /// ```
462
+ /// > [1, 2, 3].modifyAt(1) { n => n + 100 }
463
+ /// Some([1, 102, 3])
464
+ ///
465
+ /// > [1, 2, 3].modifyAt(10) { n => n + 100 }
466
+ /// None()
467
+ /// ```
468
+ ///
469
+ /// O(N)
470
470
  def modifyAt[A](list: List[A], index: Int) { update: A => A }: List[A] / Exception[OutOfBounds] = {
471
471
  list.splitAt(index) match {
472
472
  case (left, Cons(x, right)) =>
@@ -475,69 +475,69 @@ def modifyAt[A](list: List[A], index: Int) { update: A => A }: List[A] / Excepti
475
475
  }
476
476
  }
477
477
 
478
- // Delete the element at given index in the list.
479
- //
480
- // Example:
481
- // ```
482
- // > [1, 2, 3, 4].deleteAt(1)
483
- // [1, 3, 4]
484
- //
485
- // > [1, 2, 3, 4].deleteAt(-1)
486
- // [1, 2, 3, 4]
487
- //
488
- // > [1, 2, 3, 4].deleteAt(10)
489
- // [1, 2, 3, 4]
490
- // ```
491
- //
492
- // O(N)
478
+ /// Delete the element at given index in the list.
479
+ ///
480
+ /// Example:
481
+ /// ```
482
+ /// > [1, 2, 3, 4].deleteAt(1)
483
+ /// [1, 3, 4]
484
+ ///
485
+ /// > [1, 2, 3, 4].deleteAt(-1)
486
+ /// [1, 2, 3, 4]
487
+ ///
488
+ /// > [1, 2, 3, 4].deleteAt(10)
489
+ /// [1, 2, 3, 4]
490
+ /// ```
491
+ ///
492
+ /// O(N)
493
493
  def deleteAt[A](list: List[A], index: Int): List[A] = {
494
494
  val left = list.slice(0, index)
495
495
  val right = list.slice(index + 1, list.size())
496
496
  left.append(right)
497
497
  }
498
498
 
499
- // Add an element at given index in the list.
500
- //
501
- // Examples:
502
- // ```
503
- // > [1, 2, 3].insert(-1, 0)
504
- // [0, 1, 2, 3]
505
- //
506
- // > [1, 2, 3].insert(0, 0)
507
- // [0, 1, 2, 3]
508
- //
509
- // > [1, 2, 3].insert(1, 0)
510
- // [1, 0, 2, 3]
511
- //
512
- // > [1, 2, 3].insert(3, 0)
513
- // [1, 2, 3, 0]
514
- //
515
- // > [1, 2, 3].insert(10, 0)
516
- // [1, 2, 3, 0]
517
- // ```
518
- //
519
- // O(N)
499
+ /// Add an element at given index in the list.
500
+ ///
501
+ /// Examples:
502
+ /// ```
503
+ /// > [1, 2, 3].insert(-1, 0)
504
+ /// [0, 1, 2, 3]
505
+ ///
506
+ /// > [1, 2, 3].insert(0, 0)
507
+ /// [0, 1, 2, 3]
508
+ ///
509
+ /// > [1, 2, 3].insert(1, 0)
510
+ /// [1, 0, 2, 3]
511
+ ///
512
+ /// > [1, 2, 3].insert(3, 0)
513
+ /// [1, 2, 3, 0]
514
+ ///
515
+ /// > [1, 2, 3].insert(10, 0)
516
+ /// [1, 2, 3, 0]
517
+ /// ```
518
+ ///
519
+ /// O(N)
520
520
  def insert[A](list: List[A], index: Int, x: A): List[A] = {
521
521
  val (left, right) = list.splitAt(index)
522
522
  left.append(Cons(x, right))
523
523
  }
524
524
 
525
- // Replace an element at given index in the list.
526
- // Returns the original list when the index is out of bounds.
527
- //
528
- // Examples:
529
- // ```
530
- // > [1, 2, 3].replace(0, 42)
531
- // [42, 2, 3]
532
- //
533
- // > [1, 2, 3].replace(-1, 42)
534
- // [1, 2, 3]
535
- //
536
- // > [1, 2, 3].replace(10, 42)
537
- // [1, 2, 3]
538
- // ```
539
- //
540
- // O(N)
525
+ /// Replace an element at given index in the list.
526
+ /// Returns the original list when the index is out of bounds.
527
+ ///
528
+ /// Examples:
529
+ /// ```
530
+ /// > [1, 2, 3].replace(0, 42)
531
+ /// [42, 2, 3]
532
+ ///
533
+ /// > [1, 2, 3].replace(-1, 42)
534
+ /// [1, 2, 3]
535
+ ///
536
+ /// > [1, 2, 3].replace(10, 42)
537
+ /// [1, 2, 3]
538
+ /// ```
539
+ ///
540
+ /// O(N)
541
541
  def replace[A](list: List[A], index: Int, x: A): List[A] = {
542
542
  if (index < 0 || index >= list.size()) {
543
543
  list
@@ -548,25 +548,25 @@ def replace[A](list: List[A], index: Int, x: A): List[A] = {
548
548
  }
549
549
  }
550
550
 
551
- // Produce a list of pairs from a pair of lists.
552
- // The length of the result is the minimum of lengths of the two lists.
553
- //
554
- // Examples:
555
- // ```
556
- // > zip([1, 2, 3], [100, 200, 300])
557
- // [(1, 100), (2, 200), (3, 300)]
558
- //
559
- // > zip([1, 2, 3], Nil[Int]())
560
- // []
561
- //
562
- // > zip(Nil[Int](), [1, 2, 3])
563
- // []
564
- //
565
- // > zip([1, 2, 3], [42])
566
- // [(1, 42)]
567
- // ```
568
- //
569
- // O(N)
551
+ /// Produce a list of pairs from a pair of lists.
552
+ /// The length of the result is the minimum of lengths of the two lists.
553
+ ///
554
+ /// Examples:
555
+ /// ```
556
+ /// > zip([1, 2, 3], [100, 200, 300])
557
+ /// [(1, 100), (2, 200), (3, 300)]
558
+ ///
559
+ /// > zip([1, 2, 3], Nil[Int]())
560
+ /// []
561
+ ///
562
+ /// > zip(Nil[Int](), [1, 2, 3])
563
+ /// []
564
+ ///
565
+ /// > zip([1, 2, 3], [42])
566
+ /// [(1, 42)]
567
+ /// ```
568
+ ///
569
+ /// O(N)
570
570
  def zip[A, B](left: List[A], right: List[B]): List[(A, B)] = {
571
571
  def go(acc: List[(A, B)], left: List[A], right: List[B]): List[(A, B)] = {
572
572
  (left, right) match {
@@ -580,25 +580,25 @@ def zip[A, B](left: List[A], right: List[B]): List[(A, B)] = {
580
580
  go(Nil(), left, right)
581
581
  }
582
582
 
583
- // Combine two lists with the given function.
584
- // The length of the result is the minimum of lengths of the two lists.
585
- //
586
- // Examples:
587
- // ```
588
- // > zipWith([1, 2, 3], [100, 200, 300]) { (a, b) => a + b }
589
- // [101, 202, 303]
590
- //
591
- // > zipWith([1, 2, 3], Nil[Int]()) { (a, b) => a + b }
592
- // []
593
- //
594
- // > zipWith(Nil[Int](), [1, 2, 3]) { (a, b) => a + b }
595
- // []
596
- //
597
- // > zipWith([1, 2, 3], [42]) { (a, b) => a + b }
598
- // [43]
599
- // ```
600
- //
601
- // O(N)
583
+ /// Combine two lists with the given function.
584
+ /// The length of the result is the minimum of lengths of the two lists.
585
+ ///
586
+ /// Examples:
587
+ /// ```
588
+ /// > zipWith([1, 2, 3], [100, 200, 300]) { (a, b) => a + b }
589
+ /// [101, 202, 303]
590
+ ///
591
+ /// > zipWith([1, 2, 3], Nil[Int]()) { (a, b) => a + b }
592
+ /// []
593
+ ///
594
+ /// > zipWith(Nil[Int](), [1, 2, 3]) { (a, b) => a + b }
595
+ /// []
596
+ ///
597
+ /// > zipWith([1, 2, 3], [42]) { (a, b) => a + b }
598
+ /// [43]
599
+ /// ```
600
+ ///
601
+ /// O(N)
602
602
  def zipWith[A, B, C](left: List[A], right: List[B]) { combine : (A, B) => C }: List[C] = {
603
603
  def go(acc: List[C], left: List[A], right: List[B]): List[C] = {
604
604
  (left, right) match {
@@ -612,15 +612,15 @@ def zipWith[A, B, C](left: List[A], right: List[B]) { combine : (A, B) => C }: L
612
612
  go(Nil(), left, right)
613
613
  }
614
614
 
615
- // Produce a pair of lists from a list of pairs.
616
- //
617
- // Examples:
618
- // ```
619
- // > [(1, 100), (2, 200), (3, 300)].unzip()
620
- // ([1, 2, 3], [100, 200, 300])
621
- // ```
622
- //
623
- // O(N)
615
+ /// Produce a pair of lists from a list of pairs.
616
+ ///
617
+ /// Examples:
618
+ /// ```
619
+ /// > [(1, 100), (2, 200), (3, 300)].unzip()
620
+ /// ([1, 2, 3], [100, 200, 300])
621
+ /// ```
622
+ ///
623
+ /// O(N)
624
624
  def unzip[A, B](pairs: List[(A, B)]): (List[A], List[B]) = {
625
625
  pairs match {
626
626
  case Nil() => (Nil(), Nil())
@@ -630,11 +630,11 @@ def unzip[A, B](pairs: List[(A, B)]): (List[A], List[B]) = {
630
630
  }
631
631
  }
632
632
 
633
- // Partition a given list into two lists.
634
- // The left list contains the elements that satsify the predicate,
635
- // the right list contains the elements that do not.
636
- //
637
- // O(N)
633
+ /// Partition a given list into two lists.
634
+ /// The left list contains the elements that satsify the predicate,
635
+ /// the right list contains the elements that do not.
636
+ ///
637
+ /// O(N)
638
638
  def partition[A](l: List[A]) { pred: A => Bool }: (List[A], List[A]) = {
639
639
  var lefts: List[A] = Nil()
640
640
  var rights: List[A] = Nil()
@@ -649,11 +649,11 @@ def partition[A](l: List[A]) { pred: A => Bool }: (List[A], List[A]) = {
649
649
  (lefts.reverse, rights.reverse)
650
650
  }
651
651
 
652
- // Sort a list using a given comparison function.
653
- //
654
- // Note: this implementation is not stacksafe!
655
- //
656
- // O(N log N)
652
+ /// Sort a list using a given comparison function.
653
+ ///
654
+ /// Note: this implementation is not stacksafe!
655
+ ///
656
+ /// O(N log N)
657
657
  def sortBy[A](l: List[A]) { compare: (A, A) => Bool }: List[A] =
658
658
  l match {
659
659
  case Nil() => Nil()
@@ -667,9 +667,9 @@ def sortBy[A](l: List[A]) { compare: (A, A) => Bool }: List[A] =
667
667
  def sort(l: List[Int]): List[Int] = l.sortBy { (a, b) => a < b }
668
668
  def sort(l: List[Double]): List[Double] = l.sortBy { (a, b) => a < b }
669
669
 
670
- // Check if a list is sorted according to the given comparison function.
671
- //
672
- // O(N)
670
+ /// Check if a list is sorted according to the given comparison function.
671
+ ///
672
+ /// O(N)
673
673
  def isSortedBy[A](list: List[A]) { compare: (A, A) => Bool }: Bool = {
674
674
  def go(list: List[A]): Bool = {
675
675
  list match {