Antra

Standardbibliothek

Antra::Option

import Antra::Option

Option type utilities for Antra.

Antra::Option provides helpers around %Some[...] / %None[] values and registers official propagation support for postfix ?.

Überblick#

Fuer 0-oder-1-Werte gibt es jetzt auch ein kleines Option-Paket:

import Antra::Option as Option

println(Option.some(42))
println(Option.none())
println(Option.map(%Some[2], |x| -> x * 10))

Praktisch sind vor allem:

  • Option.some(value) und Option.none()
  • Option.map(...), Option.and_then(...), Option.flatten(...)
  • Option.unwrap(...), Option.lazy_unwrap(...), Option.or(...)
  • Option.is_some(...) und Option.is_none(...)

Auch Antra::Option registriert offizielle Propagate-Impls fuer .^. Fuer lokales Entpacken ohne fruehes Weiterreichen gibt es zusaetzlich .?.

Hier ist wichtig: opt ist in diesem Beispiel bereits ein %Some[...]- oder %None[]-Wert. Das postfixe .^ entpackt also den Erfolgsfall und reicht %None[] bei Bedarf hart weiter:

import Antra::Option as Option

fn maybe_inc(opt) -> {
    val x = opt.^
    %Some[x + 1]
}

println(maybe_inc(%Some[1]))
println(maybe_inc(%None[]))

Wenn du dagegen erst einen nackten Wert in eine Option heben willst, passiert das bewusst vor dem .^:

import Antra::Option as Option

fn lift(x) -> %Some[x]

fn maybe_inc_plain(x) -> {
    val y = lift(x).^ 
    %Some[y + 1]
}

println(maybe_inc_plain(1))

Wenn du dagegen nicht frueh %None[] weiterreichen willst, sondern lokal nur den inneren Wert oder undef brauchst, ist .? die passende Form:

fn maybe_inc_or_zero(opt) -> {
    val x = opt.? // 0
    x + 1
}

println(maybe_inc_or_zero(%Some[1]))
println(maybe_inc_or_zero(%None[]))

Die Kurzlesart ist also:

  • opt.^ bedeutet: ich habe schon eine Option und will sie entpacken oder %None[] frueh weiterreichen
  • opt.? bedeutet: ich habe schon eine Option und will lokal den Wert oder undef
  • %Some[x] oder eine Helper-Funktion wie lift(x) bedeutet: ich baue erst eine Option-Huelle

Die eigentlichen Impls liegen analog in Antra::Propagate::Option.

Die ausfuehrliche Praxis-Einordnung dazu steht in 11-fehlerstile-und-result-apis.md.

Funktionen#

fn and_then(option :- Option[T], f :- fn(T) -> Option[U]) :- Option[U]

Calls f(v) if %Some[v], otherwise passes %None[] through.

Example:

Option.and_then(%Some[2], |x| -> %Some[x * 10])   # => %Some[20]
Option.and_then(%None[], |x| -> %Some[x * 10])    # => %None[]

or

use x <- Option.and_then(head([1, 2, 3]))
println(x * 10)   # => 10

If head(...) returns %None[], the remaining top-level code after the use line is not executed.

The equivalent Propagate-style form would be:

val x = head([1, 2, 3]).^
println(x * 10)   # => 10
fn flatten(option :- Option[Option[T]]) :- Option[T]

Flattens a nested Option: %Some[%Some[x]] becomes %Some[x].

Example:

Option.flatten(%Some[%Some[7]])   # => %Some[7]
Option.flatten(%Some[%None[]])    # => %None[]
fn is_none(option :- Option[T]) :- Bool

Returns true if the option is %None[].

fn is_some(option :- Option[T]) :- Bool

Returns true if the option is %Some[...].

fn lazy_unwrap(option :- Option[T], f :- fn() -> T) :- T

Like unwrap, but evaluates f() lazily for %None[].

Example:

Option.lazy_unwrap(%Some[7], || -> 0)   # => 7
Option.lazy_unwrap(%None[], || -> 99)   # => 99
fn map(option :- Option[T], f :- fn(T) -> U) :- Option[U]

Transforms the value inside %Some[...] with f.

Example:

Option.map(%Some[3], |x| -> x + 1)   # => %Some[4]
Option.map(%None[], |x| -> x + 1)    # => %None[]
fn none() :- Option[T]

Returns %None[].

Example:

Option.none()   # => %None[]
fn ok_or(option :- Option[T], error :- E) :- Result[T, E]

Converts %Some[v] to %Ok[v] and %None[] to %Err[error].

Useful when a lookup is optional locally, but the caller expects a proper error channel.

Example:

Option.ok_or(head(users), "missing user")
# => %Ok[user] | %Err["missing user"]
fn ok_or_else(option :- Option[T], f :- fn() -> E) :- Result[T, E]

Like ok_or, but computes the error lazily with f().

Example:

Option.ok_or_else(head(users), || -> error("missing user", [site: :caller]))
fn or(first :- Option[T], second :- Option[T]) :- Option[T]

Returns first if it is %Some[...], otherwise second.

Example:

Option.or(%Some[1], %Some[2])   # => %Some[1]
Option.or(%None[], %Some[2])    # => %Some[2]
fn some(value :- T) :- Option[T]

Wraps a value in %Some[...].

Example:

Option.some(42)   # => %Some[42]
fn unwrap(option :- Option[T], default :- T) :- T

Extracts the value from %Some[v] or returns default.

Example:

Option.unwrap(%Some[7], 0)   # => 7
Option.unwrap(%None[], 0)    # => 0

Quelle dieser Seite