Как помочь системе вывода типов вывести тип аргумента замыкания? - PullRequest
1 голос
/ 12 января 2020

У меня есть это замыкание color, но система типов не может определить тип его аргумента pixel.

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()
}

С аннотированным типом оно становится

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()
};

Есть ли какие-нибудь хитрости, которые помогут системе типов вывести тип pixel без аннотирования?

1 Ответ

4 голосов
/ 13 января 2020

До сих пор я не мог придумать что-то без аннотаций, но вы могли бы уменьшить количество аннотаций:

Вы могли бы оставить некоторые дыры, которые должны быть заполнены выводом типа:

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()
}

В качестве альтернативы, 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()
}

В качестве альтернативы, сделайте color локальным 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()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...