29
29
//! );
30
30
//! assert_eq!(folded, 9001);
31
31
//!
32
- //! // Mapping over an HList
33
32
//! let h3 = hlist![9000, "joe", 41f32];
34
- //! let mapped = h3.map(hlist![
35
- //! |n| n + 1,
36
- //! |s| s,
37
- //! |f| f + 1f32]);
33
+ //! // Mapping over an HList (we use as_ref() to map over the HList without consuming it,
34
+ //! // but you can use the value-consuming version by leaving it off.)
35
+ //! let mapped = h3.as_ref().map(hlist![
36
+ //! |&n| n + 1,
37
+ //! |&s| s,
38
+ //! |&f| f + 1f32]);
38
39
//! assert_eq!(mapped, hlist![9001, "joe", 42f32]);
39
40
//!
40
41
//! // Plucking a value out by type
@@ -112,6 +113,10 @@ impl HList for HNil {
112
113
}
113
114
}
114
115
116
+ impl AsRef < HNil > for HNil {
117
+ fn as_ref ( & self ) -> & HNil { self }
118
+ }
119
+
115
120
/// Represents the most basic non-empty HList. Its value is held in `head`
116
121
/// while its tail is another HList.
117
122
#[ derive( PartialEq , Debug , Eq , Clone , Copy , PartialOrd , Ord ) ]
@@ -126,6 +131,10 @@ impl<H, T: HList> HList for HCons<H, T> {
126
131
}
127
132
}
128
133
134
+ impl < H , T > AsRef < HCons < H , T > > for HCons < H , T > {
135
+ fn as_ref ( & self ) -> & HCons < H , T > { self }
136
+ }
137
+
129
138
impl < H , T > HCons < H , T > {
130
139
/// Returns the head of the list and the tail of the list as a tuple2.
131
140
/// The original list is consumed
@@ -160,7 +169,7 @@ impl<H, T> HCons<H, T> {
160
169
/// assert_eq!(h2, 1.23f32);
161
170
/// ```
162
171
pub fn h_cons < H , T : HList > ( h : H , tail : T ) -> HCons < H , T > {
163
- tail . prepend ( h )
172
+ HCons { head : h , tail : tail }
164
173
}
165
174
166
175
/// Returns an `HList` based on the values passed in.
@@ -440,8 +449,8 @@ impl<Source> Sculptor<HNil, HNil> for Source {
440
449
/// Index for Plucking the first item of type THead out of Self and the rest (IndexTail) is for the
441
450
/// Plucker's remainder induce.
442
451
impl < THead , TTail , SHead , STail , IndexHead , IndexTail > Sculptor < HCons < THead , TTail > ,
443
- HCons < IndexHead , IndexTail > >
444
- for HCons < SHead , STail >
452
+ HCons < IndexHead , IndexTail > >
453
+ for HCons < SHead , STail >
445
454
where HCons < SHead , STail > : Plucker < THead , IndexHead > ,
446
455
<HCons < SHead , STail > as Plucker < THead , IndexHead > >:: Remainder : Sculptor < TTail , IndexTail >
447
456
{
@@ -452,9 +461,9 @@ impl<THead, TTail, SHead, STail, IndexHead, IndexTail> Sculptor<HCons<THead, TTa
452
461
self . pluck ( ) ;
453
462
let ( tail, tail_remainder) : ( TTail , Self :: Remainder ) = r. sculpt ( ) ;
454
463
( HCons {
455
- head : p,
456
- tail : tail,
457
- } ,
464
+ head : p,
465
+ tail : tail,
466
+ } ,
458
467
tail_remainder)
459
468
}
460
469
}
@@ -498,10 +507,10 @@ impl<H, Tail> IntoReverse for HCons<H, Tail>
498
507
499
508
fn into_reverse ( self ) -> Self :: Output {
500
509
self . tail . into_reverse ( ) +
501
- HCons {
502
- head : self . head ,
503
- tail : HNil ,
504
- }
510
+ HCons {
511
+ head : self . head ,
512
+ tail : HNil ,
513
+ }
505
514
}
506
515
}
507
516
@@ -547,6 +556,17 @@ impl<F> HMappable<F> for HNil {
547
556
}
548
557
}
549
558
559
+ impl < ' a , F , R , H > HMappable < HCons < F , HNil > > for & ' a HCons < H , HNil >
560
+ where F : Fn ( & ' a H ) -> R {
561
+ type Output = HCons < R , HNil > ;
562
+
563
+ fn map ( self , f : HCons < F , HNil > ) -> Self :: Output {
564
+ let ref h = self . head ;
565
+ let f = f. head ;
566
+ HCons { head : f ( h) , tail : HNil }
567
+ }
568
+ }
569
+
550
570
impl < F , MapperHeadR , MapperTail , H , Tail > HMappable < HCons < F , MapperTail > > for HCons < H , Tail >
551
571
where F : FnOnce ( H ) -> MapperHeadR ,
552
572
Tail : HMappable < MapperTail >
@@ -561,6 +581,23 @@ impl<F, MapperHeadR, MapperTail, H, Tail> HMappable<HCons<F, MapperTail>> for HC
561
581
}
562
582
}
563
583
584
+ impl < ' a , F , MapperHeadR , MapperTail , H , Tail > HMappable < HCons < F , MapperTail > > for & ' a HCons < H , Tail >
585
+ where F : Fn ( & ' a H ) -> MapperHeadR ,
586
+ & ' a Tail : HMappable < MapperTail >
587
+ {
588
+ type Output = HCons < MapperHeadR , <& ' a Tail as HMappable < MapperTail > >:: Output > ;
589
+ fn map ( self , mapper : HCons < F , MapperTail > ) -> Self :: Output {
590
+ let f = mapper. head ;
591
+ let mapper_tail = mapper. tail ;
592
+ let ref self_head = self . head ;
593
+ let ref self_tail = self . tail ;
594
+ HCons {
595
+ head : f ( self_head) ,
596
+ tail : self_tail. map ( mapper_tail) ,
597
+ }
598
+ }
599
+ }
600
+
564
601
/// Foldr for HLists
565
602
pub trait HFoldRightable < Folder , Init > {
566
603
type Output ;
@@ -602,7 +639,7 @@ impl<F, Init> HFoldRightable<F, Init> for HNil {
602
639
}
603
640
604
641
impl < F , FolderHeadR , FolderTail , H , Tail , Init > HFoldRightable < HCons < F , FolderTail > , Init >
605
- for HCons < H , Tail >
642
+ for HCons < H , Tail >
606
643
where Tail : HFoldRightable < FolderTail , Init > ,
607
644
F : FnOnce ( H , <Tail as HFoldRightable < FolderTail , Init > >:: Output ) -> FolderHeadR
608
645
{
@@ -655,7 +692,7 @@ impl<F, Acc> HFoldLeftable<F, Acc> for HNil {
655
692
}
656
693
657
694
impl < F , FolderHeadR , FolderTail , H , Tail , Acc > HFoldLeftable < HCons < F , FolderTail > , Acc >
658
- for HCons < H , Tail >
695
+ for HCons < H , Tail >
659
696
where Tail : HFoldLeftable < FolderTail , FolderHeadR > ,
660
697
F : FnOnce ( Acc , H ) -> FolderHeadR
661
698
{
@@ -772,10 +809,14 @@ mod tests {
772
809
#[ test]
773
810
#[ allow( non_snake_case) ]
774
811
fn test_Hlist_macro ( ) {
775
- let h1: Hlist ! ( i32 , & str , i32 ) = hlist ! [ 1 , "2" , 3 ] ;
776
- let h2: Hlist ! ( i32 , & str , i32 , ) = hlist ! [ 1 , "2" , 3 ] ;
777
- let h3: Hlist ! ( i32 ) = hlist ! [ 1 ] ;
778
- let h4: Hlist ! ( i32 , ) = hlist ! [ 1 , ] ;
812
+ let h1: Hlist
813
+ ! ( i32 , & str , i32 ) = hlist ! [ 1 , "2" , 3 ] ;
814
+ let h2: Hlist
815
+ ! ( i32 , & str , i32 , ) = hlist ! [ 1 , "2" , 3 ] ;
816
+ let h3: Hlist
817
+ ! ( i32 ) = hlist ! [ 1 ] ;
818
+ let h4: Hlist
819
+ ! ( i32 , ) = hlist ! [ 1 , ] ;
779
820
assert_eq ! ( h1, h2) ;
780
821
assert_eq ! ( h3, h4) ;
781
822
}
@@ -838,9 +879,22 @@ mod tests {
838
879
}
839
880
840
881
#[ test]
841
- fn test_map ( ) {
882
+ fn test_map_consuming ( ) {
883
+ let h = hlist ! [ 9000 , "joe" , 41f32 ] ;
884
+ let mapped = h. map ( hlist ! [
885
+ |n| n + 1 ,
886
+ |s| s,
887
+ |f| f + 1f32 ] ) ;
888
+ assert_eq ! ( mapped, hlist![ 9001 , "joe" , 42f32 ] ) ;
889
+ }
890
+
891
+ #[ test]
892
+ fn test_map_non_consuming ( ) {
842
893
let h = hlist ! [ 9000 , "joe" , 41f32 ] ;
843
- let mapped = h. map ( hlist ! [ |n| n + 1 , |s| s, |f| f + 1f32 ] ) ;
894
+ let mapped = h. as_ref ( ) . map ( hlist ! [
895
+ |& n| n + 1 ,
896
+ |& s| s,
897
+ |& f| f + 1f32 ] ) ;
844
898
assert_eq ! ( mapped, hlist![ 9001 , "joe" , 42f32 ] ) ;
845
899
}
846
900
0 commit comments