Option<T> class
class Option<T> { static final _none = new Option._internal(false, null); final T _value; final bool isDefined; Option._internal(this.isDefined, this._value); factory Option.none() => _none; factory Option.some(T value) => new Option._internal(true, value); factory Option.fromNullable(T nullableValue) => nullableValue == null ? _none : new Option.some(nullableValue); T get value { if (isDefined) return _value; throw new StateError('Option.none() has no value'); } T get asNullable => isDefined ? _value : null; T orElse(T defaultValue) => isDefined ? _value : defaultValue; T orElseCompute(T defaultValue()) => isDefined ? _value : defaultValue(); /// [:forall U, Option<U> map(U f(T value)):] Option map(f(T value)) => isDefined ? new Option.some(f(_value)) : this; /// [:forall U, Option<U> map(Option<U> f(T value)):] Option expand(Option f(T value)) => isDefined ? f(_value) : this; /// Precondition: [:this is Option<Option>:] Option get flattened { assert(isDefined ? _value is Option : true); return orElse(_none); } bool operator ==(Option<T> other) => (isDefined && other.isDefined && _value == other._value) || (!isDefined && !other.isDefined); int get hashCode => asNullable.hashCode; String toString() => isDefined ? "Option.some($_value)" : "Option.none()"; }
Constructors
factory Option.fromNullable(T nullableValue) #
factory Option.fromNullable(T nullableValue) => nullableValue == null ? _none : new Option.some(nullableValue);
factory Option.none() #
factory Option.none() => _none;
Properties
final Option flattened #
Precondition: this is Option<Option>
Option get flattened { assert(isDefined ? _value is Option : true); return orElse(_none); }
final int hashCode #
Get a hash code for this object.
All objects have hash codes. Hash codes are guaranteed to be the
same for objects that are equal when compared using the equality
operator ==
. Other than that there are no guarantees about
the hash codes. They will not be consistent between runs and
there are no distribution guarantees.
If a subclass overrides hashCode it should override the equality operator as well to maintain consistency.
int get hashCode => asNullable.hashCode;
Operators
bool operator ==(Option<T> other) #
The equality operator.
The default behavior for all Objects is to return true if and
only if this
and
other are the same object.
Override this method to specify a different equality relation on a class. The overriding method must still be an equivalence relation. That is, it must be:
-
Total: It must return a boolean for all arguments. It should never throw or return
null
. -
Reflexive: For all objects
o
,o == o
must be true. -
Symmetric: For all objects
o1
ando2
,o1 == o2
ando2 == o1
must either both be true, or both be false. -
Transitive: For all objects
o1
,o2
, ando3
, ifo1 == o2
ando2 == o3
are true, theno1 == o3
must be true.
The method should also be consistent over time, so equality of two objects should not change over time, or at least only change if one of the objects was modified.
If a subclass overrides the equality operator it should override the hashCode method as well to maintain consistency.
bool operator ==(Option<T> other) => (isDefined && other.isDefined && _value == other._value) || (!isDefined && !other.isDefined);
Methods
Option expand(Option f(T value)) #
forall U, Option<U> map(Option<U> f(T value))
Option expand(Option f(T value)) => isDefined ? f(_value) : this;
Option map(f(T value)) #
forall U, Option<U> map(U f(T value))
Option map(f(T value)) => isDefined ? new Option.some(f(_value)) : this;