Options
Calibre uses option types for values that may or may not be present.
An option type is written as T?.
let maybe_number : int? = some(9);let nothing : int? = none;Options are useful when the absence of a value is expected and not really an error.
const area_of_triangle := fn (a b c : float) -> float? => if a + b > c && b + c > a && c + a > b => some(1f) else => none;You can inspect an option with match.
match some(12) { .Some : value => print(value), .None => print("no value")};if let is often even more convenient.
if let .Some : value <- some(12) => { print(value);};try is useful with option-style flows too, especially when you want a default value if the option is empty.
let value := try some(12) => 0;Like results, try supports a few forms:
let a := try some_option;let b := try some_option => fallback_value;Options also have standard helper methods.
let maybe := some(9).map(fn (n : int) -> int => n * 2).unwrap_or(0);print(maybe);Common helpers include:
.is_some().is_none().unwrap().unwrap_or(...).map(...).and_then(...)
For example:
let value := some(5) .and_then(fn (x : int) -> int? => if x > 3 => some(x * 3) else => none) .unwrap_or(0);Use options when a value may simply be missing and results when you need to explain why something failed.