Results
Calibre uses result types for error-aware computations.
A result type is written as Err!Ok, where the left side is the error type and the right side is the ok type.
const parse_and_add := fn (txt : str, extra : int) -> str!int => { let n := try txt as int; ok(n + extra);};In str!int, str is the error type and int is the successful value type.
Results are commonly created with ok(...) and err(...).
ok(10);err("something went wrong");You can inspect results with pattern matching.
match parse_and_add("50", 7) { .Ok : value => print(value), .Err : message => print(message)};Calibre also provides the try keyword for working with results more conveniently.
Here, if txt as int fails, the error is propagated instead of continuing.
const parse_and_add := fn (txt : str, extra : int) -> str!int => { let n := try txt as int; ok(n + extra);};try can also take a fallback expression with =>.
let number := try "64" as int => 0;In this form, if the result is successful, the success value is produced. If it fails, the expression after => is used instead.
You can also bind the error value with : name =>.
In this form, the error is bound to e and can be inspected or transformed before choosing what to do next.
let file := try File.open_read("input.txt") : e => { panic(e);};These forms are all valid:
let a := try some_result;let b := try some_result => fallback_value;let c := try some_result : err_value => fallback_expression;Use plain try value; when you want to propagate failure, try value => ... when you want a fallback, and try value : err => ... when you also need access to the error itself.
Results come with standard helper methods.
let parsed := parse_and_add("50", 7);
print(parsed.is_ok());print(parsed.is_err());print(parsed.unwrap_or(0));You can transform results with methods like .map(...) and .map_err(...).
let res1 := ok(7).map(fn (x : int) -> int => x * 2);let res2 := err("oops").map_err(fn (e : str) -> str => "ERR: " & e);Use results when an operation can fail and you want that possibility to be visible in the type system.