Option type
A.k.a Maybe
(Haskell), Optional
(Java 8)
Models the absence of value
ā In the sense of a possibility for a value to be absent
ā ā unit
: used in the case where there is never a value
Defined as a union with 2 cases :
Common use cases:
Modeling an optional field
Turning a partial operation into a total operation
Modeling an optional field
ā Make it explicit that Name
is mandatory and Civility
optional
ā Warning: this design does not prevent Name = null
here (BCL limit)
Partial to total operation
An operation is partial when no output value is possible for certain inputs.
The operation can become total by wrapping the result in an
option
,None
being used when the operation gives no output.
Example 1: inverse of a number
Function
Operation
Signature
n = 0.5
n = 0.0
inverse
Partial
float -> float
2.0
infinity
ā
tryInverse
Total
float -> float option
Some 2.0
None
š
Example 2: find an element in a collection
Partial operation:
find predicate
ā š„ when item not foundTotal operation:
tryFind predicate
āNone
orSome item
Benefits š
Explicit, honest / partial operation
No special value:
null
,infinity
No exception
Forces calling code to handle all cases:
Some value
ā output value givenNone .....
ā output value missing
Control flow
How to test for the presence of the value (of type 'T
) in the option?
ā Do not use
if option.IsSome then ... option.Value
patternā Do pattern match the option
ā Do use
Option.xxx
functions
Control flow with pattern matching
Example:
Control flow with Option.xxx
helpers
Option.xxx
helpersMapping of the inner value (of type 'T
) if present:
ā map f option
with f
total operation 'T -> 'U
ā bind f option
with f
partial operation 'T -> 'U option
Keep value if present and if conditions are met:
ā filter predicate option
with predicate: 'T -> bool
called only if value present
Exercise
Implement map
, bind
and filter
with pattern matching
Example
Advantages
Makes business logic more readable
No
if hasValue then / else
Highlight the happy path
Handle corner cases at the end
š” Alternative syntax more light: ad-hoc computation expressions š
Option
: comparison with other types
Option
: comparison with other typesOption
vsList
Option
vsNullable
Option
vsnull
Option
vs List
Option
vs List
Conceptually closed
ā Option ā List of 0 or 1 items
ā See Option.toList
function: 't option -> 't list
(None -> []
, Some x -> [x]
)
š” Option
& List
modules: many functions with the same name
ā contains
, count
, exist
, filter
, fold
, forall
, map
ā A List
can have more than 1 element
ā Type Option
models absence of value better than type List
Option
vs Nullable
Option
vs Nullable
System.Nullable<'T>
ā Option<'T>
but more limited
ā Does not work for reference types
ā Lacks monadic behavior i.e.
map
andbind
functionsā Lacks built-in pattern matching
Some x | None
ā In FāÆ, no magic as in C⯠/ keyword
null
Example:
š C⯠uses Nullable
whereas F⯠uses only Option
. However, Nullable
can be required with some libraries, for instance to deal with nullable columns in a database.
Option
vs null
Option
vs null
Due to the interop with the BCL, F⯠has to deal with null
objects in some cases.
š Good practice: isolate these cases and wrap them in an Option
type.
Nullable reference types
F⯠9 introduces nullable reference types: a type-safe way to deal with reference types that can have null
as a valid value.
This feature must be activated:
Adds
<Nullable>enable</Nullable>
in your.fsproj
Passes
--checknulls+
options todotnet fsi
- seeFSharp.FSIExtraInteractiveParameters
settings in vscode
Then, | null
needs to be added to the type annotation to indicate that null
as a valid value. It's really similar to nullable reference types: F⯠string | null
is equivalent to C⯠string?
, with the usual tradeoff for explicitness over terseness/magic.
Last updated
Was this helpful?