A function like
fn sum(i: impl Iterator<Item = i32>) -> i32 {
let mut acc = 0;
for x in i {acc += x;}
acc
}
can be used as:
let a = &[1, 2, 3, 4];
println!("{}", sum(a.iter().cloned()));
So far, so good. But now you want to have as well:
fn main() -> std::io::Result<()> {
use std::{fs::File, io::BufReader, io::BufRead};
let file = BufReader::new(File::open("/dev/stdin")?);
let stream = file.lines()
.map(|s| s.unwrap().parse::<i32>().unwrap());
println!("{}", sum(stream));
Ok(())
}
From this, however, I draw the conclusion that sum
has a has the wrong signature. The proper one is:
fn sum<E>(a: impl Iterator<Item = Result<i32, E>>)
-> Result<i32, E>
{
let mut acc = 0;
for x in a {acc += x?;}
Ok(acc)
}
type Error = Box<dyn std::error::Error>;
fn main() -> Result<(), Error> {
use std::{fs::File, io::BufReader, io::BufRead};
let file = BufReader::new(File::open("/dev/stdin")?);
let stream = file.lines()
.map(|s| Ok::<i32, Error>(s?.parse::<i32>()?));
println!("{:?}", sum(stream)?);
Ok(())
}
Consequently, we need to rephrase:
enum Zero {}
fn main() {
let a = &[1, 2, 3, 4];
let value = match sum(a.iter().cloned().map(Ok::<i32, Zero>)) {
Ok(value) => value,
_ => unreachable!()
};
println!("{}", value);
}
Is there any other conclusion to draw?