]>
Commit | Line | Data |
---|---|---|
6a06907d XL |
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); | |
1b1a35ee | 98 | } |