There is one use I can think of, and it's something that has been considered as an improvement to the Swift programming language.
Swift has a maybe
Monad, spelled Optional<T>
or T?
. There are many ways to interact with it.
You can use conditional unwrapping like
if let nonOptional = someOptional {
print(nonOptional)
}
else {
print("someOptional was nil")
}
You can use map
, flatMap
to transform the values
- The force unwrap operator (
!
, of type (T?) -> T
) to forcefully unwrap the contents, otherwise triggering a crash
The nil-coalescing operator (??
, of type (T?, T) -> T
) to take its value or otherwise use a default value:
let someI = Optional(100)
print(someI ?? 123) => 100 // "left operand is non-nil, unwrap it.
let noneI: Int? = nil
print(noneI ?? 123) // => 123 // left operand is nil, take right operand, acts like a "default" value
Unfortunately, there was no concise way of saying "unwrap or throw an error" or "unwrap or crash with a custom error message". Something like
let someI: Int? = Optional(123)
let nonOptionalI: Int = someI ?? fatalError("Expected a non-nil value")
doesn't compile, because fatalError
has type () -> Never
(()
is Void
, Swift' unit type, Never
is Swift's bottom type). Calling it produces Never
, which isn't compatible with the T
expected as a right operand of ??
.
In an attempt to remedy this, Swift Evolution propsoal SE-0217
- The “Unwrap or Die” operator was put forth. It was ultimately rejected, but it raised interest in making Never
be a subtype of all types.
If Never
was made to be a subtype of all types, then the previous example will be compilable:
let someI: Int? = Optional(123)
let nonOptionalI: Int = someI ?? fatalError("Expected a non-nil value")
because the call site of ??
has type (T?, Never) -> T
, which would be compatible with the (T?, T) -> T
signature of ??
.
(x ? 3 : throw new Exception())
gets replaced for analysis purposes with something more like(x ? 3 : absurd(throw new Exception()))
?