I have code using a nested Result like this:
fn ip4(s: &str) -> Result<(u8, u8, u8, u8), num::ParseIntError> {
let t: Vec<_> = s.split('.').collect();
match t[0].parse::<u8>() {
Ok(a1) => {
match t[1].parse::<u8>() {
Ok(a2) => {
match t[2].parse::<u8>() {
Ok(a3) => {
match t[3].parse::<u8>() {
Ok(a4) => {
Ok((a1, a2, a3, a4))
}
Err(er) => Err(er)
}
},
Err(er) => Err(er)
}
}
Err(er) => Err(er)
}
}
Err(er) => Err(er),
}
}
Is there any function or composing way to reduce this? Something like Haskell or Scala programmers do:
fn ip4(s: &str) -> Result<(u8, u8, u8, u8), num::ParseIntError> {
let t: Vec<_> = s.split('.').collect();
Result
.lift((,,,))
.ap(() -> t[0].parse::<u8>())
.ap(() -> t[1].parse::<u8>())
.ap(() -> t[2].parse::<u8>())
.ap(() -> t[3].parse::<u8>()) // maybe more concise in Haskell or Scala but I think it's enough :)
}