-
Notifications
You must be signed in to change notification settings - Fork 530
/
hlists.scala
718 lines (596 loc) · 29.4 KB
/
hlists.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
/*
* Copyright (c) 2011-15 Miles Sabin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package shapeless
package syntax
import scala.annotation.tailrec
/**
* Carrier for `HList` operations.
*
* These methods are implemented here and pimped onto the minimal `HList` types to avoid issues that would otherwise be
* caused by the covariance of `::[H, T]`.
*
* @author Miles Sabin
*/
final class HListOps[L <: HList](l : L) extends Serializable {
import ops.adjoin.Adjoin
import ops.hlist._
/**
* Returns the head of this `HList`. Available only if there is evidence that this `HList` is composite.
*/
def head(implicit c : IsHCons[L]) : c.H = c.head(l)
/**
* Returns the tail of this `HList`. Available only if there is evidence that this `HList` is composite.
*/
def tail(implicit c : IsHCons[L]) : c.T = c.tail(l)
/**
* Prepend the argument element to this `HList`.
*/
def ::[H](h : H) : H :: L = shapeless.::(h, l)
/**
* Prepend the argument element to this `HList`.
*/
def +:[H](h : H) : H :: L = shapeless.::(h, l)
/**
* Append the argument element to this `HList`.
*/
def :+[T](t : T)(implicit prepend : Prepend[L, T :: HNil]) : prepend.Out = prepend(l, t :: HNil)
/**
* Append the argument `HList` to this `HList`.
*/
def ++[S <: HList](suffix : S)(implicit prepend : Prepend[L, S]) : prepend.Out = prepend(l, suffix)
/**
* Prepend the argument `HList` to this `HList`.
*/
def ++:[P <: HList](prefix : P)(implicit prepend : Prepend[P, L]) : prepend.Out = prepend(prefix, l)
/**
* Prepend the argument `HList` to this `HList`.
*/
def :::[P <: HList](prefix : P)(implicit prepend : Prepend[P, L]) : prepend.Out = prepend(prefix, l)
/**
* Prepend the reverse of the argument `HList` to this `HList`.
*/
def reverse_:::[P <: HList](prefix : P)(implicit prepend : ReversePrepend[P, L]) : prepend.Out = prepend(prefix, l)
/**
* Returns the ''nth'' element of this `HList`. An explicit type argument must be provided. Available only if there is
* evidence that this `HList` has at least ''n'' elements.
*/
def apply[N <: Nat](implicit at : At[L, N]) : at.Out = at(l)
/**
* Returns the ''nth'' element of this `HList`. Available only if there is evidence that this `HList` has at least ''n''
* elements.
*/
def apply(n : Nat)(implicit at : At[L, n.N]) : at.Out = at(l)
/**
* Returns the ''nth'' element of this `HList`. An explicit type argument must be provided. Available only if there is
* evidence that this `HList` has at least ''n'' elements.
*/
def at[N <: Nat](implicit at : At[L, N]) : at.Out = at(l)
/**
* Returns the ''nth'' element of this `HList`. Available only if there is evidence that this `HList` has at least ''n''
* elements.
*/
def at(n : Nat)(implicit at : At[L, n.N]) : at.Out = at(l)
/**
* Returns the last element of this `HList`. Available only if there is evidence that this `HList` is composite.
*/
def last(implicit last : Last[L]) : last.Out = last(l)
/**
* Returns an `HList` consisting of all the elements of this `HList` except the last. Available only if there is
* evidence that this `HList` is composite.
*/
def init(implicit init : Init[L]) : init.Out = init(l)
/**
* Returns the first element of type `U` of this `HList`. An explicit type argument must be provided. Available only
* if there is evidence that this `HList` has an element of type `U`.
*/
def select[U](implicit selector : Selector[L, U]) : U = selector(l)
/**
* Returns the elements of this `HList` specified by `Ids`. Available only if there is
* evidence that this `HList` contains all elements specified in `Ids`.
*/
case class SelectManyAux[L <: HList](l: L) extends NatProductArgs {
def applyNatProduct[Ids <: HList](implicit sel: SelectMany[L,Ids]): sel.Out = sel(l)
}
def selectManyType[Ids <: HList](implicit sel: SelectMany[L, Ids]): sel.Out = sel(l)
def selectMany = SelectManyAux(l)
/**
* Returns the elements of this `HList` specified by the range of ids in [A,B[
* Available only if there is evidence that this `HList` contains all elements in that range
*/
def selectRange[A <: Nat, B <: Nat](implicit sel: SelectRange[L,A,B]): sel.Out = sel(l)
def selectRange(a : Nat, b : Nat)(implicit sel: SelectRange[L,a.N,b.N]): sel.Out = sel(l)
/**
* Returns all elements of type `U` of this `HList`. An explicit type argument must be provided.
*/
def filter[U](implicit partition : Partition[L, U]) : partition.Prefix = partition.filter(l)
/**
* Returns all elements of type different than `U` of this `HList`. An explicit type argument must be provided.
*/
def filterNot[U](implicit partition : Partition[L, U]) : partition.Suffix = partition.filterNot(l)
def partition[U](implicit partition: Partition[L, U]): (partition.Prefix, partition.Suffix) = partition(l)
def partitionP[U]
(implicit partition: Partition[L, U]): partition.Prefix :: partition.Suffix :: HNil = partition.product(l)
/**
* Returns the first element of type `U` of this `HList` plus the remainder of the `HList`. An explicit type argument
* must be provided. Available only if there is evidence that this `HList` has an element of type `U`.
*
* The `Elem` suffix is here to avoid creating an ambiguity with RecordOps#remove and should be removed if
* SI-5414 is resolved in a way which eliminates the ambiguity.
*/
def removeElem[U](implicit remove : Remove[L, U]): remove.Out = remove(l)
/**
* Returns the first elements of this `HList` that have types in `SL` plus the remainder of the `HList`. An expicit
* type argument must be provided. Available only if there is evidence that this `HList` contains elements with
* types in `SL`.
*/
def removeAll[SL <: HList](implicit removeAll : RemoveAll[L, SL]): removeAll.Out = removeAll(l)
/**
* Returns the union between this `HList` and another `HList`. In case of duplicate types, this operation is a
* order-preserving multi-set union. If type `T` appears n times in this `HList` and m > n times in `M`, the
* resulting `HList` contains the first n elements of type `T` in this `HList`, followed by the last m - n element
* of type `T` in `M`.
*/
def union[M <: HList](s: M)(implicit union: Union[L, M]): union.Out = union(l, s)
/**
* Returns the intersection between this `HList` and another `HList`. In case of duplicate types, this operation is a
* multiset intersection. If type `T` appears n times in this `HList` and m < n times in `M`, the resulting `HList`
* contains the first m elements of type `T` in this `HList`.
* Also available if `M` contains types absent in this `HList`.
*/
def intersect[M <: HList](implicit intersection: Intersection[L, M]): intersection.Out = intersection(l)
/**
* Returns the difference between this `HList` and another `HList`. In case of duplicate types, this operation is a
* multiset difference. If type `T` appears n times in this `HList` and m < n times in `M`, the resulting `HList`
* contains the last n - m elements of type `T` in this `HList`.
* Also available if `M` contains types absent in this `HList`.
*/
def diff[M <: HList](implicit diff: Diff[L, M]): diff.Out = diff(l)
/**
* Reinserts an element `U` into this `HList` to return another `HList` `O`.
*/
def reinsert[O <: HList] = new ReinsertAux[O]
class ReinsertAux[O <: HList] {
def apply[U](u: U)(implicit remove: Remove.Aux[O, U, (U, L)]): O = remove.reinsert((u, l))
}
/**
* Reinserts the elements of `SL` into this `HList` to return another `HList` `O`.
*/
def reinsertAll[O <: HList] = new ReinsertAllAux[O]
class ReinsertAllAux[O <: HList] {
def apply[SL <: HList](sl: SL)(implicit removeAll: RemoveAll.Aux[O, SL, (SL, L)]): O = removeAll.reinsert((sl, l))
}
/**
* Replaces the first element of type `U` of this `HList` with the supplied value, also of type `U` returning both
* the replaced element and the updated `HList`. Available only if there is evidence that this `HList` has an element
* of type `U`.
*/
def replace[U](u : U)(implicit replacer : Replacer[L, U, U]): replacer.Out = replacer(l, u)
class ReplaceTypeAux[U] {
def apply[V](v : V)(implicit replacer : Replacer[L, U, V]): replacer.Out = replacer(l, v)
}
/**
* Replaces the first element of type `U` of this `HList` with the supplied value of type `V`, returning both the
* replaced element and the updated `HList`. An explicit type argument must be provided for `U`. Available only if
* there is evidence that this `HList` has an element of type `U`.
*/
def replaceType[U] = new ReplaceTypeAux[U]
/**
* Replaces the first element of type `U` of this `HList` with the supplied value, also of type `U`. Available only
* if there is evidence that this `HList` has an element of type `U`.
*
* The `Elem` suffix is here to avoid creating an ambiguity with RecordOps#updated and should be removed if
* SI-5414 is resolved in a way which eliminates the ambiguity.
*/
def updatedElem[U, Out <: HList](u : U)
(implicit replacer : Replacer.Aux[L, U, U, (U, Out)]) : Out = replacer(l, u)._2
/**
* Replaces the first element of type `U` of this `HList` with the result of its transformation to a `V` via the
* supplied function. Available only if there is evidence that this `HList` has an element of type `U`.
*/
def updateWith[U, V, Out <: HList](f : U => V)
(implicit replacer : Modifier.Aux[L, U, V, (U, Out)]) : Out = replacer.apply(l, f)._2
/**
* Replaces the `N`th element of this `HList` with the result of calling the supplied function on it.
* Available only if there is evidence that this `HList` has `N` elements.
*
* @author Andreas Koestler
*/
def updateAtWith[V](n: NatWith[({ type λ[n <: Nat] = At[L, n]})#λ])(f: n.instance.Out => V)
(implicit upd: ModifierAt[L, n.N, n.instance.Out, V]): upd.Out = upd(l, f)
class UpdatedTypeAux[U] {
def apply[V, Out <: HList](v : V)
(implicit replacer : Replacer.Aux[L, U, V, (U, Out)]) : Out = replacer(l, v)._2
}
/**
* Replaces the first element of type `U` of this `HList` with the supplied value of type `V`. An explicit type
* argument must be provided for `U`. Available only if there is evidence that this `HList` has an element of
* type `U`.
*/
def updatedType[U] = new UpdatedTypeAux[U]
class UpdatedAtAux[N <: Nat] {
def apply[U, V, Out <: HList](u : U)(implicit replacer : ReplaceAt.Aux[L, N, U, (V, Out)]) : Out = replacer(l, u)._2
}
/**
* Replaces the ''nth' element of this `HList` with the supplied value of type `U`. An explicit type argument
* must be provided for `N`. Available only if there is evidence that this `HList` has at least ''n'' elements.
*/
def updatedAt[N <: Nat] = new UpdatedAtAux[N]
/**
* Replaces the ''nth' element of this `HList` with the supplied value of type `U`. Available only if there is
* evidence that this `HList` has at least ''n'' elements.
*/
def updatedAt[U, V, Out <: HList](n: Nat, u : U)(implicit replacer : ReplaceAt.Aux[L, n.N, U, (V, Out)]) : Out = replacer(l, u)._2
/**
* Returns the first ''n'' elements of this `HList`. An explicit type argument must be provided. Available only if
* there is evidence that this `HList` has at least ''n'' elements.
*/
def take[N <: Nat](implicit take : Take[L, N]) : take.Out = take(l)
/**
* Returns the first ''n'' elements of this `HList`. Available only if there is evidence that this `HList` has at
* least ''n'' elements.
*/
def take(n : Nat)(implicit take : Take[L, n.N]) : take.Out = take(l)
/**
* Returns all but the first ''n'' elements of this `HList`. An explicit type argument must be provided. Available
* only if there is evidence that this `HList` has at least ''n'' elements.
*/
def drop[N <: Nat](implicit drop : Drop[L, N]) : drop.Out = drop(l)
/**
* Returns all but the first ''n'' elements of this `HList`. Available only if there is evidence that this `HList`
* has at least ''n'' elements.
*/
def drop(n : Nat)(implicit drop : Drop[L, n.N]) : drop.Out = drop(l)
/**
* Splits this `HList` at the ''nth'' element, returning the prefix and suffix as a pair. An explicit type argument
* must be provided. Available only if there is evidence that this `HList` has at least ''n'' elements.
*/
def split[N <: Nat](implicit split : Split[L, N]) : (split.Prefix, split.Suffix) = split(l)
def splitP[N <: Nat](implicit split : Split[L, N]) : split.Prefix :: split.Suffix :: HNil = split.product(l)
/**
* Splits this `HList` at the ''nth'' element, returning the prefix and suffix as a pair. Available only if there is
* evidence that this `HList` has at least ''n'' elements.
*/
def split(n : Nat)(implicit split : Split[L, n.N]) : (split.Prefix, split.Suffix) = split(l)
def splitP(n : Nat)(implicit split : Split[L, n.N]) : split.Prefix :: split.Suffix :: HNil = split.product(l)
/**
* Splits this `HList` at the ''nth'' element, returning the reverse of the prefix and suffix as a pair. An explicit
* type argument must be provided. Available only if there is evidence that this `HList` has at least ''n'' elements.
*/
def reverse_split[N <: Nat](implicit split : ReverseSplit[L, N]) : (split.Prefix, split.Suffix) = split(l)
def reverse_splitP[N <: Nat]
(implicit split : ReverseSplit[L, N]) : split.Prefix :: split.Suffix :: HNil = split.product(l)
/**
* Splits this `HList` at the ''nth'' element, returning the reverse of the prefix and suffix as a pair. Available
* only if there is evidence that this `HList` has at least ''n'' elements.
*/
def reverse_split(n : Nat)(implicit split : ReverseSplit[L, n.N]) : (split.Prefix, split.Suffix) = split(l)
def reverse_splitP(n : Nat)
(implicit split : ReverseSplit[L, n.N]) : split.Prefix :: split.Suffix :: HNil = split.product(l)
/**
* Splits this `HList` at the first occurrence of an element of type `U`, returning the prefix and suffix as a pair.
* An explicit type argument must be provided. Available only if there is evidence that this `HList` has an element
* of type `U`.
*/
def splitLeft[U](implicit split : SplitLeft[L, U]) : (split.Prefix, split.Suffix) = split(l)
def splitLeftP[U](implicit split : SplitLeft[L, U]) : split.Prefix :: split.Suffix :: HNil = split.product(l)
/**
* Splits this `HList` at the first occurrence of an element of type `U`, returning reverse of the prefix and suffix
* as a pair. An explicit type argument must be provided. Available only if there is evidence that this `HList` has
* an element of type `U`.
*/
def reverse_splitLeft[U](implicit split : ReverseSplitLeft[L, U]) : (split.Prefix, split.Suffix) = split(l)
def reverse_splitLeftP[U]
(implicit split : ReverseSplitLeft[L, U]) : split.Prefix :: split.Suffix :: HNil = split.product(l)
/**
* Splits this `HList` at the last occurrence of an element of type `U`, returning the prefix and suffix as a pair.
* An explicit type argument must be provided. Available only if there is evidence that this `HList` has an element
* of type `U`.
*/
def splitRight[U](implicit split : SplitRight[L, U]) : (split.Prefix, split.Suffix) = split(l)
def splitRightP[U](implicit split : SplitRight[L, U]) : split.Prefix :: split.Suffix :: HNil = split.product(l)
/**
* Splits this `HList` at the last occurrence of an element of type `U`, returning reverse of the prefix and suffix
* as a pair. An explicit type argument must be provided. Available only if there is evidence that this `HList` has
* an element of type `U`.
*/
def reverse_splitRight[U](implicit split : ReverseSplitRight[L, U]) : (split.Prefix, split.Suffix) = split(l)
def reverse_splitRightP[U]
(implicit split : ReverseSplitRight[L, U]) : split.Prefix :: split.Suffix :: HNil = split.product(l)
/**
* Permutes this `HList` into the same order as another `HList`. An explicit type argument must be supplied.
* Available only if both `HList`s have elements of the same types.
*/
def align[M <: HList](implicit align: Align[L, M]): M = align(l)
/**
* Permutes this `HList` into the same order as the supplied `HList` with the same element types. Available only if
* both `HList`s have elements of the same types.
*/
def align[M <: HList](m: M)(implicit align: Align[L, M]): M = align(l)
/**
* Reverses this `HList`.
*/
def reverse(implicit reverse : Reverse[L]) : reverse.Out = reverse(l)
/**
* Maps a higher rank function across this `HList`.
*/
def map(f : Poly)(implicit mapper : Mapper[f.type, L]) : mapper.Out = mapper(l)
/**
* Flatmaps a higher rank function across this `HList`.
*/
def flatMap(f : Poly)(implicit mapper : FlatMapper[f.type, L]) : mapper.Out = mapper(l)
/**
* Conses an element onto each row of this HMatrix (HList of HLists).
*/
def mapCons[A](a: A)(implicit mapCons: MapCons[A, L]): mapCons.Out = mapCons(a, l)
/**
* Replaces each element of this `HList` with a constant value.
*/
def mapConst[C](c : C)(implicit mapper : ConstMapper[C, L]) : mapper.Out = mapper(c, l)
/**
* Collect a higher rank function across this `HList`.
*/
def collect(p: Poly)(implicit collect: Collect[L, p.type]): collect.Out = collect(l)
/**
* Maps a higher rank function ''f'' across this `HList` and folds the result using monomorphic combining operator
* `op`. Available only if there is evidence that the result type of `f` at each element conforms to the argument
* type of ''op''.
*/
def foldMap[R](z : R)(f : Poly)(op : (R, R) => R)(implicit folder : MapFolder[L, R, f.type]) : R = folder(l, z, op)
/**
* Computes a left fold over this `HList` using the polymorphic binary combining operator `op`. Available only if
* there is evidence `op` can consume/produce all the partial results of the appropriate types.
*/
def foldLeft[R](z : R)(op : Poly)(implicit folder : LeftFolder[L, R, op.type]) : folder.Out = folder(l, z)
/**
* Computes a right fold over this `HList` using the polymorphic binary combining operator `op`. Available only if
* there is evidence `op` can consume/produce all the partial results of the appropriate types.
*/
def foldRight[R](z : R)(op : Poly)(implicit folder : RightFolder[L, R, op.type]) : folder.Out = folder(l, z)
/**
* Computes a left reduce over this `HList` using the polymorphic binary combining operator `op`. Available only if
* there is evidence that this `HList` has at least one element and that `op` can consume/produce all the partial
* results of the appropriate types.
*/
def reduceLeft(op : Poly)(implicit reducer : LeftReducer[L, op.type]) : reducer.Out = reducer(l)
/**
* Computes a right reduce over this `HList` using the polymorphic binary combining operator `op`. Available only if
* there is evidence that this `HList` has at least one element and that `op` can consume/produce all the partial
* results of the appropriate types.
*/
def reduceRight(op : Poly)(implicit reducer : RightReducer[L, op.type]) : reducer.Out = reducer(l)
/**
* Zips this `HList` with its argument `HList` returning an `HList` of pairs.
*/
def zip[R <: HList](r : R)(implicit zipper : Zip[L :: R :: HNil]) : zipper.Out = zipper(l :: r :: HNil)
/**
* Zips this `HList` of monomorphic function values with its argument `HList` of correspondingly typed function
* arguments returning the result of each application as an `HList`. Available only if there is evidence that the
* corresponding function and argument elements have compatible types.
*/
def zipApply[A <: HList](a : A)(implicit zipper : ZipApply[L, A]) : zipper.Out = zipper(l, a)
/**
* Zips this `HList` of `HList`s returning an `HList` of tuples. Available only if there is evidence that this
* `HList` has `HList` elements.
*/
def zip(implicit zipper : Zip[L]) : zipper.Out = zipper(l)
/**
* Zips this `HList` of `HList`s returning an `HList` of tuples. Available only if there is evidence that this
* `HList` has `HList` elements.
*/
@deprecated("Use zip instead", "2.0.0")
def zipped(implicit zipper : Zip[L]) : zipper.Out = zipper(l)
/**
* Unzips this `HList` of tuples returning a tuple of `HList`s. Available only if there is evidence that this
* `HList` has tuple elements.
*/
def unzip(implicit unzipper : Unzip[L]) : unzipper.Out = unzipper(l)
/**
* Unzips this `HList` of tuples returning a tuple of `HList`s. Available only if there is evidence that this
* `HList` has tuple elements.
*/
@deprecated("Use unzip instead", "2.0.0")
def unzipped(implicit unzipper : Unzip[L]) : unzipper.Out = unzipper(l)
/**
* Zips this `HList` with its argument `HList` of `HList`s, returning an `HList` of `HList`s with each element of
* this `HList` prepended to the corresponding `HList` element of the argument `HList`.
*/
def zipOne[T <: HList](t : T)(implicit zipOne : ZipOne[L, T]) : zipOne.Out = zipOne(l, t)
/**
* Zips this `HList` with a constant, resulting in an `HList` of tuples of the form
* ({element from this `HList`}, {supplied constant})
*/
def zipConst[C](c: C)(implicit zipConst: ZipConst[C, L]): zipConst.Out = zipConst(c, l)
/**
* Zips this 'HList' with its argument 'HList' using argument 'Poly2', returning an 'HList'.
* Doesn't require this to be the same length as its 'HList' argument, but does require evidence that its
* 'Poly2' argument is defined at their intersection.
*/
def zipWith[R <: HList, P <: Poly2](r: R)(p: P)(implicit zipWith: ZipWith[L, R, P]): zipWith.Out =
zipWith(l, r)
/**
* Zips this `HList` with its element indices, resulting in a 'HList' of tuples of the form
* ({element from input tuple}, {element index})
*
* @author Andreas Koestler
*/
def zipWithIndex(implicit zipWithIndex: ZipWithIndex[L]): zipWithIndex.Out = zipWithIndex(l)
/**
* Transposes this `HList`.
*/
def transpose(implicit transpose : Transposer[L]) : transpose.Out = transpose(l)
/**
* Returns an `HList` typed as a repetition of the least upper bound of the types of the elements of this `HList`.
*/
def unify(implicit unifier : Unifier[L]) : unifier.Out = unifier(l)
/**
* Returns an `HList` with all elements that are subtypes of `B` typed as `B`.
*/
def unifySubtypes[B](implicit subtypeUnifier : SubtypeUnifier[L, B]) : subtypeUnifier.Out = subtypeUnifier(l)
/**
* Converts this `HList` to a correspondingly typed tuple.
*/
def tupled(implicit tupler : Tupler[L]) : tupler.Out = tupler(l)
/**
* Compute the length of this `HList`.
*/
def length(implicit length : Length[L]) : length.Out = length()
/**
* Compute the length of this `HList` as a runtime Int value.
*/
def runtimeLength: Int = {
@tailrec def loop(l: HList, acc: Int): Int = l match {
case HNil => acc
case hd :: tl => loop(tl, acc+1)
}
loop(l, 0)
}
/**
* Convert this `HList` to a `List[Any]`.
*/
def runtimeList: List[Any] = {
val builder = List.newBuilder[Any]
@tailrec def loop(l: HList): Unit = l match {
case HNil => ()
case hd :: tl =>
builder += hd
loop(tl)
}
loop(l)
builder.result
}
/**
* Converts this `HList` to a `M` of elements typed as the least upper bound of the types of the elements
* of this `HList`.
*/
def to[M[_]](implicit ts : ToTraversable[L, M]) : ts.Out = ts(l)
/**
* Converts this `HList` to an ordinary `List` of elements typed as the least upper bound of the types of the elements
* of this `HList`.
*/
def toList[Lub](implicit toTraversableAux : ToTraversable.Aux[L, List, Lub]) : toTraversableAux.Out = toTraversableAux(l)
/**
* Converts this `HList` to an `Array` of elements typed as the least upper bound of the types of the elements
* of this `HList`.
*
* It is advisable to specify the type parameter explicitly, because for many reference types, case classes in
* particular, the inferred type will be too precise (ie. `Product with Serializable with CC` for a typical case class
* `CC`) which interacts badly with the invariance of `Array`s.
*/
def toArray[Lub](implicit toTraversableAux : ToTraversable.Aux[L, Array, Lub]) : toTraversableAux.Out = toTraversableAux(l)
/**
* Converts this `HList` to a `M` of elements embedded in a minimal `Coproduct` encompassing the types of every
* elements of this `HList`.
*
* For example :
*
* (1 :: "qux" :: 42 :: "bar" :: HNil).toCoproduct[Vector]
*
* Would return a Vector[Int :+: String :+: CNil]
*
* Note that the `M` container must extend `Traversable`, which means that `Array` cannot be used.
*/
def toCoproduct[M[_] <: Traversable[_]](implicit toCoproductTraversable: ToCoproductTraversable[L, M]): toCoproductTraversable.Out = toCoproductTraversable(l)
/**
* Converts this `HList` to a - sized - `M` of elements typed as the least upper bound of the types of the elements
* of this `HList`.
*/
def toSized[M[_]](implicit ts : ToSized[L, M]) : ts.Out = ts(l)
/**
* Displays all elements of this hlist in a string using start, end, and separator strings.
*/
def mkString(start: String, sep: String, end: String)
(implicit toTraversable: ToTraversable.Aux[L, List, Any]): String = this.toList.mkString(start, sep, end)
/**
* Converts this `HList` of values into a record with the provided keys.
*/
def zipWithKeys[K <: HList](keys: K)(implicit withKeys: ZipWithKeys[K, L]): withKeys.Out = withKeys(l)
/**
* Converts this `HList` of values into a record with given keys. A type argument must be provided.
*/
def zipWithKeys[K <: HList](implicit withKeys: ZipWithKeys[K, L]): withKeys.Out = withKeys(l)
/**
* Returns all permutations of this 'HList'
*/
def permutations(implicit permutations: Permutations[L]): permutations.Out = permutations(l)
/**
* Rotate this 'HList' left by N. An explicit type argument must be provided.
*/
def rotateLeft[N <: Nat](implicit rotateLeft: RotateLeft[L, N]): rotateLeft.Out = rotateLeft(l)
/**
* Rotate this 'HList' left by N
*/
def rotateLeft(n: Nat)(implicit rotateLeft: RotateLeft[L, n.N]): rotateLeft.Out = rotateLeft(l)
/**
* Rotate this 'HList' right by N. An explicit type argument must be provided.
*/
def rotateRight[N <: Nat](implicit rotateRight: RotateRight[L, N]): rotateRight.Out = rotateRight(l)
/**
* Rotate this 'HList' right by N
*/
def rotateRight(n: Nat)(implicit rotateRight: RotateRight[L, n.N]): rotateRight.Out = rotateRight(l)
/**
* Computes a left scan over this `HList` using the polymorphic binary combining operator `op`. Available only if
* there is evidence `op` can consume/produce all the results of the appropriate types.
*/
def scanLeft[A, P <: Poly](z: A)(op: Poly)(implicit scanL: LeftScanner[L, A, op.type]): scanL.Out = scanL(l, z)
/**
* Computes a right scan over this `HList` using the polymorphic binary combining operator `op`. Available only if
* there is evidence `op` can consume/produce all the results of the appropriate types.
*/
def scanRight[A, P <: Poly](z: A)(op: Poly)(implicit scanR: RightScanner[L, A, op.type]): scanR.Out = scanR(l, z)
/**
*
* Produces a new `HList` where a slice of this `HList` is replaced by another. Available only if there are at least
* ``n`` plus ``m`` elements.
*/
def patch[In <: HList](n: Nat, in: In, m: Nat)(implicit patcher: Patcher[n.N, m.N, L, In]): patcher.Out = patcher(l, in)
/**
* Produces a new `HList` where a slice of this `HList` is replaced by another. Two explicit type arguments must be
* provided. Available only if there are at least `N` plus `M` elements.
*/
def patch[N <: Nat, M <: Nat] = new PatchAux[N, M]
class PatchAux[N <: Nat, M <: Nat]{
def apply[In <: HList](in: In)(implicit patcher: Patcher[N, M, L, In]): patcher.Out = patcher(l, in)
}
/**
* Adjoins the elements of this `HList` by flattening any `HList` elements.
*/
def adjoined(implicit adjoin: Adjoin[L]): adjoin.Out = adjoin(l)
/**
* Finds the first element of the HList for which the given Poly is defined, and applies the Poly to it.
*/
def collectFirst[P <: Poly](p: P)(implicit collect: CollectFirst[L, p.type]): collect.Out = collect(l)
/**
* Groups the elements of this `HList` into tuples of `n` elements, offset by `step`
*
* @author Andreas Koestler
*/
def group(n: Nat, step: Nat)(implicit grouper: Grouper[L, n.N, step.N]): grouper.Out = grouper(l)
/**
* Groups the elements of this `HList` into tuples of `n` elements, offset by `step`
* Use elements in `pad` as necessary to complete last group up to `n` items.
* @author Andreas Koestler
*/
def group[Pad <: HList](n: Nat, step: Nat, pad: Pad)(implicit grouper: PaddedGrouper[L, n.N, step.N, Pad]): grouper.Out = grouper(l, pad)
/**
* Appends `elem` until a given length `N` is reached.
*/
def padTo[A](n: Nat, elem: A)(implicit padTo: PadTo[n.N, A, L]): padTo.Out = padTo(elem, l)
/**
* Slices beginning at index `from` and afterwards, up until index `until`
*/
def slice(from: Nat, until: Nat)(implicit slice: Slice[from.N, until.N, L]): slice.Out = slice(l)
}