std/core/option
std/core/src/option.trb
Absence as a value: Option, its two cases, and the vocabulary that works on the value that is there.
Value? is the only absence in the language - there is no null and no uninitialized field - so a signature says
whether a value can be missing, and the caller has to answer for it. The answers are ?? for a fallback, ?. for a
step that keeps the absence, and match for both ways at once.
Related
type Option
type Option<Value> with OrElse<Value>
A value that may be absent. Value? is sugar for Option<Value>.
Reach for it where nothing is a legitimate answer: a lookup that finds no entry, a list that has no first element, a
field that is filled in later. map, flatMap, filter and forEach mean the same as everywhere else (see "One
Vocabulary" in CONCEPT.md) and run immediately - an Option is a value, not a pipeline.
Examples
const first = [1, 2, 3].first()
print(first ?? 0)
The two cases are what a match covers, and neither of them needs a type in front of it: the prelude imports both.
const found: Int? = None
const text = match found {
Some(value) => "{value}"
None => "nothing"
}
print text
Pitfalls
- An
Option<Option<Value>>is two questions and not one.Option.flatMapis what answers both at once, which is also why a lookup that returns an Option is chained withflatMapand not withmap.
Open
There is no combinator that takes a second Option (or, zip): two of them are combined with Option.flatMap and
a closure.
Related
Option.orElse- the??operator, and the only way to leave the type.Result- what to return instead when the absence has a reason.
case Some
case Some(value: Value)
The value is there.
case None
case None
There is no value.
fn isSome
fn isSome(): Bool
Whether there is a value. For the value itself, match or ?? instead.
fn isNone
fn isNone(): Bool
Whether the value is absent.
fn map
fn map<Output>(transform: Transform<Value, Output>): Output?
Changes the value if there is one, and keeps the absence if there is none.
Examples
const name: String? = Some "ada"
print name.map({ _.toUpperCase() })
fn flatMap
fn flatMap<Output>(transform: Transform<Value, Output?>): Output?
Changes the value into another Option and keeps one level: for a step that can answer with nothing itself.
Examples
const names = ["ada": "Ada Lovelace"]
const initial = names.get("ada").flatMap({ _.chars().first() })
print initial
fn filter
fn filter(predicate: Predicate<Value>): Value?
Keeps the value only if it answers the question, and turns it into None if it does not.
fn forEach
fn forEach(action: Action<Value>)
Runs the action if there is a value: the statement form of Option.map, for a step that answers with nothing.
fn toList
fn toList(): List<Value>
Into the world of pipelines: a list with no or one element.
fn orElse
fn orElse(fallback: lazy Value): Value
The value, or the fallback if there is none. This is the ?? operator, and the way out of the type.
The fallback is lazy, so it is only evaluated when it is needed: a fallback that reads a file or counts costs
nothing while the value is there.
Examples
const missing: Int? = None
print missing.orElse(0)
fn okOr
fn okOr<Failure>(error: lazy Failure): Result<Value, Failure>
Gives the absence a reason and makes it a Result, which is what a function that answers with ? needs.
Examples
const found: Int? = None
print found.okOr("there is no number")
fn expect
fn expect(message: String): Value
The value, with the message as the reason if there is none. For a place where the absence is a bug.
Panics
When there is no value. Nothing else runs after that, so Option.orElse or Option.okOr is what a program that
has to carry on uses instead.
extend Option<Value> with Show
extend<Value: Show> Option<Value> with Show
Some(value) or the bare None - a case with fields is written out, a case without one is its name.
fn show
fn show(): String
extend Option<Target> with From<Iterate<Value?>>
extend<Value, Target: From<Iterate<Value>>> Option<Target> with From<Iterate<Value?>>
All or nothing: names.map(findUser).to<List<User>?>() is Some(users) if every user was found.
Stops pulling at the first None.
fn from
static fn from(value: Iterate<Value?>): Target?