1
+ #![ recursion_limit = "128" ]
2
+
3
+ #[ macro_use]
4
+ extern crate generic_array;
5
+
6
+ use generic_array:: typenum:: consts:: U4 ;
7
+
8
+ use std:: fmt:: Debug ;
9
+ use std:: ops:: Add ;
10
+
11
+ use generic_array:: { GenericArray , ArrayLength } ;
12
+ use generic_array:: sequence:: * ;
13
+ use generic_array:: functional:: * ;
14
+
15
+ /// Example function using generics to pass N-length sequences and map them
16
+ pub fn generic_map < S > ( s : S )
17
+ where
18
+ S : FunctionalSequence < i32 > , // `.map`
19
+ S :: Item : Add < i32 , Output = i32 > , // `x + 1`
20
+ S : MappedGenericSequence < i32 , i32 > , // `i32` -> `i32`
21
+ MappedSequence < S , i32 , i32 > : Debug , // println!
22
+ {
23
+ let a = s. map ( |x| x + 1 ) ;
24
+
25
+ println ! ( "{:?}" , a) ;
26
+ }
27
+
28
+ /// Complex example function using generics to pass N-length sequences, zip them, and then map that result.
29
+ ///
30
+ /// If used with `GenericArray` specifically this isn't necessary
31
+ pub fn generic_sequence_zip_sum < A , B > ( a : A , b : B ) -> i32
32
+ where
33
+ A : FunctionalSequence < i32 > , // `.zip`
34
+ B : FunctionalSequence < i32 , Length = A :: Length > , // `.zip`
35
+ A : MappedGenericSequence < i32 , i32 > , // `i32` -> `i32`
36
+ B : MappedGenericSequence < i32 , i32 , Mapped = MappedSequence < A , i32 , i32 > > , // `i32` -> `i32`, prove A and B can map to the same output
37
+ A :: Item : Add < B :: Item , Output = i32 > , // `l + r`
38
+ MappedSequence < A , i32 , i32 > : MappedGenericSequence < i32 , i32 > + FunctionalSequence < i32 > , // `.map`
39
+ SequenceItem < MappedSequence < A , i32 , i32 > > : Add < i32 , Output =i32 > , // `x + 1`
40
+ MappedSequence < MappedSequence < A , i32 , i32 > , i32 , i32 > : Debug , // `println!`
41
+ MappedSequence < MappedSequence < A , i32 , i32 > , i32 , i32 > : FunctionalSequence < i32 > , // `.fold`
42
+ SequenceItem < MappedSequence < MappedSequence < A , i32 , i32 > , i32 , i32 > > : Add < i32 , Output =i32 > // `x + a`, note the order
43
+ {
44
+ let c = a. zip ( b, |l, r| l + r) . map ( |x| x + 1 ) ;
45
+
46
+ println ! ( "{:?}" , c) ;
47
+
48
+ c. fold ( 0 , |a, x| x + a)
49
+ }
50
+
51
+ /// Super-simple fixed-length i32 `GenericArray`s
52
+ pub fn generic_array_plain_zip_sum ( a : GenericArray < i32 , U4 > , b : GenericArray < i32 , U4 > ) -> i32 {
53
+ a. zip ( b, |l, r| l + r) . map ( |x| x + 1 ) . fold ( 0 , |a, x| x + a)
54
+ }
55
+
56
+ pub fn generic_array_variable_length_zip_sum < N > ( a : GenericArray < i32 , N > , b : GenericArray < i32 , N > ) -> i32
57
+ where
58
+ N : ArrayLength < i32 > ,
59
+ {
60
+ a. zip ( b, |l, r| l + r) . map ( |x| x + 1 ) . fold ( 0 , |a, x| x + a)
61
+ }
62
+
63
+ pub fn generic_array_same_type_variable_length_zip_sum < T , N > ( a : GenericArray < T , N > , b : GenericArray < T , N > ) -> i32
64
+ where
65
+ N : ArrayLength < T > + ArrayLength < <T as Add < T > >:: Output > ,
66
+ T : Add < T , Output =i32 > ,
67
+ {
68
+ a. zip ( b, |l, r| l + r) . map ( |x| x + 1 ) . fold ( 0 , |a, x| x + a)
69
+ }
70
+
71
+ /// Complex example using fully generic `GenericArray`s with the same length.
72
+ ///
73
+ /// It's mostly just the repeated `Add` traits, which would be present in other systems anyway.
74
+ pub fn generic_array_zip_sum < A , B , N : ArrayLength < A > + ArrayLength < B > > ( a : GenericArray < A , N > , b : GenericArray < B , N > ) -> i32
75
+ where
76
+ A : Add < B > ,
77
+ N : ArrayLength < <A as Add < B > >:: Output > +
78
+ ArrayLength < <<A as Add < B > >:: Output as Add < i32 > >:: Output > ,
79
+ <A as Add < B > >:: Output : Add < i32 > ,
80
+ <<A as Add < B > >:: Output as Add < i32 > >:: Output : Add < i32 , Output =i32 > ,
81
+ {
82
+ a. zip ( b, |l, r| l + r) . map ( |x| x + 1 ) . fold ( 0 , |a, x| x + a)
83
+ }
84
+
85
+ #[ test]
86
+ fn test_generics ( ) {
87
+ generic_map ( arr ! [ i32 ; 1 , 2 , 3 , 4 ] ) ;
88
+
89
+ assert_eq ! ( generic_sequence_zip_sum( arr![ i32 ; 1 , 2 , 3 , 4 ] , arr![ i32 ; 2 , 3 , 4 , 5 ] ) , 28 ) ;
90
+
91
+ assert_eq ! ( generic_array_plain_zip_sum( arr![ i32 ; 1 , 2 , 3 , 4 ] , arr![ i32 ; 2 , 3 , 4 , 5 ] ) , 28 ) ;
92
+
93
+ assert_eq ! ( generic_array_variable_length_zip_sum( arr![ i32 ; 1 , 2 , 3 , 4 ] , arr![ i32 ; 2 , 3 , 4 , 5 ] ) , 28 ) ;
94
+
95
+ assert_eq ! ( generic_array_same_type_variable_length_zip_sum( arr![ i32 ; 1 , 2 , 3 , 4 ] , arr![ i32 ; 2 , 3 , 4 , 5 ] ) , 28 ) ;
96
+
97
+ assert_eq ! ( generic_array_zip_sum( arr![ i32 ; 1 , 2 , 3 , 4 ] , arr![ i32 ; 2 , 3 , 4 , 5 ] ) , 28 ) ;
98
+ }
0 commit comments