Skip to content

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.