| mod checked { |
| #[deriving(Show)] |
| enum MathError { |
| DivisionByZero, |
| NegativeLogarithm, |
| NegativeSquareRoot, |
| } |
| |
| type MathResult = Result<f64, MathError>; |
| |
| fn div(x: f64, y: f64) -> MathResult { |
| if y == 0.0 { |
| Err(DivisionByZero) |
| } else { |
| Ok(x / y) |
| } |
| } |
| |
| fn sqrt(x: f64) -> MathResult { |
| if x < 0.0 { |
| Err(NegativeSquareRoot) |
| } else { |
| Ok(x.sqrt()) |
| } |
| } |
| |
| fn ln(x: f64) -> MathResult { |
| if x < 0.0 { |
| Err(NegativeLogarithm) |
| } else { |
| Ok(x.ln()) |
| } |
| } |
| |
| // Intermediate function |
| fn op_(x: f64, y: f64) -> MathResult { |
| // if `div` "fails", then `DivisionByZero` will be `return`ed |
| let ratio = try!(div(x, y)); |
| |
| // if `ln` "fails", then `NegativeLogarithm` will be `return`ed |
| let ln = try!(ln(ratio)); |
| |
| sqrt(ln) |
| } |
| |
| pub fn op(x: f64, y: f64) { |
| match op_(x, y) { |
| Err(why) => fail!(match why { |
| NegativeLogarithm => "logarithm of negative number", |
| DivisionByZero => "division by zero", |
| NegativeSquareRoot => "square root of negative number", |
| }), |
| Ok(value) => println!("{}", value), |
| } |
| } |
| } |
| |
| fn main() { |
| checked::op(1.0, 10.0); |
| } |