Skip to content

ard/result

Ard represents recoverable errors as values with Result, commonly written with ! syntax:

fn divide(a: Int, b: Int) Int!Str {
if b == 0 {
Result::err("division by zero")
} else {
Result::ok(a / b)
}
}

Result is available from the prelude. You can also import ard/result when you want the module namespace explicitly.

Create a successful result.

let result: Int!Str = Result::ok(42)

Create a failed result.

let result: Int!Str = Result::err("failed")

Return true when the result is successful.

if result.is_ok() {
// success
}

Return true when the result is an error.

if result.is_err() {
// error
}

Return the success value or fail with message.

let value = result.expect("expected success")

Return the success value or default.

let value = result.or(0)

Transform the success value while preserving errors.

let result: Int!Str = Result::ok(21)
let doubled = result.map(fn(v: Int) Int { v * 2 })

Transform the error value while preserving success values.

let result: Int!Str = Result::err("bad")
let sized = result.map_err(fn(err: Str) Int { err.size() })

Chain another operation that can fail.

fn ensure_even(num: Int) Int!Str {
match num % 2 == 0 {
true => Result::ok(num),
false => Result::err("not even"),
}
}
let checked = Result::ok(20).and_then(ensure_even)

Use match to handle both cases:

match divide(10, 2) {
ok(value) => value,
err(message) => 0,
}

try unwraps an ok value. If the result is an error, the current function returns that error immediately.

fn add_and_divide(a: Int, b: Int, divisor: Int) Int!Str {
let sum = a + b
let result = try divide(sum, divisor)
Result::ok(result + 10)
}