Reputation: 3573
I have this closure color
, but the type system cannot infer the type of its pixel
argument.
pub fn solve_part2(input: &[u32]) -> String {
let color = |pixel| {
pixel
.skip_while(|l| **l == 2)
.next()
.map(|c| char::from_digit(*c, 10).unwrap())
.unwrap()
};
let pixel = |n| input.iter().skip(n).step_by(25 * 6);
(0..(25 * 6)).map(|px| color(pixel(px))).collect()
}
With the type annotated, it becomes
let color = |pixel: std::iter::StepBy<std::iter::Skip<std::slice::Iter<u32>>>| {
pixel
.skip_while(|l| **l == 2)
.next()
.map(|c| char::from_digit(*c, 10).unwrap())
.unwrap()
};
Are there any tricks to help the type system infer the type of pixel
without annotating?
Upvotes: 1
Views: 81
Reputation: 35983
So far, I could not come up with something without annotations, but you could reduce the amount of annotation:
You could leave some holes that are to be filled by type inference:
pub fn solve_part2(input: &[u32]) -> String {
let color = |pixel: std::iter::StepBy<_>| {
pixel
.skip_while(|l: &&_| **l == 2)
.next()
.map(|c| char::from_digit(*c, 10).unwrap())
.unwrap()
};
let pixel = |n| input.iter().skip(n).step_by(25 * 6);
(0..(25 * 6)).map(|px| color(pixel(px))).collect()
}
Alternatively, inline color
:
pub fn solve_part3(input: &[u32]) -> String {
let pixel = |n| input.iter().skip(n).step_by(25 * 6);
(0..(25 * 6)).map(|px| pixel(px)
.skip_while(|l| **l == 2)
.next()
.map(|c| char::from_digit(*c, 10).unwrap())
.unwrap()).collect()
}
Alternatively, make color
a local fn
:
pub fn solve_part3(input: &[u32]) -> String {
fn color<'a>(pixel: impl Iterator<Item=&'a u32>) -> char {
pixel
.skip_while(|l| **l == 2)
.next()
.map(|c| char::from_digit(*c, 10).unwrap())
.unwrap()
};
let pixel = |n| input.iter().skip(n).step_by(25 * 6);
(0..(25 * 6)).map(|px| color(pixel(px))).collect()
}
Upvotes: 4