The standard library presents several schemes for iterating
collections in the std::iter module. Amongst these there are the
Zip and Map iterators, however, there is no ZipWith.
It seems like you should be able to implement a zip_with function
pretty trivially something like this:
fn zipWith<R, U: Iterator, C: Fn(U::Item, U::Item) -> R> (combo: C, left: U, right: U) -> ??? {
left.zip(right).map(| (l, r) | combo(l, r))
}But, what should the return type be? Until abstract return types land
in rust, we can't return impl Iterator<R>, we can only return a
concrete implementation of an iterator -- in this case we would return
a Map.
I think this is ugly! Types should communicate the intent of a
function, and the intent of zip_with isn't (only) to Map.
So this library exposes a struct ZipWith that holds two iterators
and a closure for zipping elements together, and a trait IntoZipWith
(in the sense of std::iter::IntoIterator) that exposes the
zip_with function.
You can use it like this:
use zipWith::IntoZipWith;
use std::iter::Iterator;
#[test]
fn zipping_two_lists_of_numbers_with_plus_returns_their_sum () {
let left: Vec<u8> = vec![1, 2, 3];
let right: Vec<u8> = vec![4, 5, 6];
let result: Vec<u8> = left.zip_with(right, | l, r | l + r).collect();
assert_eq!(vec![5, 7, 9], result);
}