Se me ocurre un uso, y es algo que se ha considerado como una mejora del lenguaje de programación Swift.
Swift tiene una maybe
mónada, deletreada Optional<T>
o T?
. Hay muchas formas de interactuar con él.
Puede usar desenvoltura condicional como
if let nonOptional = someOptional {
print(nonOptional)
}
else {
print("someOptional was nil")
}
Puedes usar map
, flatMap
para transformar los valores
- El operador de desenvolvimiento forzado (
!
de tipo (T?) -> T
) para desenvolver forzosamente el contenido, de lo contrario desencadena un bloqueo
El operador de fusión nula ( ??
de tipo (T?, T) -> T
) para tomar su valor o usar un valor predeterminado:
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
Desafortunadamente, no había una forma concisa de decir "desenvolver o lanzar un error" o "desenvolver o bloquearse con un mensaje de error personalizado". Algo como
let someI: Int? = Optional(123)
let nonOptionalI: Int = someI ?? fatalError("Expected a non-nil value")
no se compila, porque fatalError
tiene tipo () -> Never
( ()
es Void
, tipo de unidad Never
Swift , es el tipo inferior de Swift). Llamarlo produce Never
, que no es compatible con lo T
esperado como un operando correcto de ??
.
En un intento de remediar esto, Swift Evolution propsoal SE-0217
: se presentó el operador " Desenvolver o morir" . Finalmente fue rechazado , pero despertó interés en hacer que Never
sea un subtipo de todo tipo.
Si Never
fue hecho para ser un subtipo de todos los tipos, entonces el ejemplo anterior será compilable:
let someI: Int? = Optional(123)
let nonOptionalI: Int = someI ?? fatalError("Expected a non-nil value")
porque el sitio de llamada de ??
tiene tipo (T?, Never) -> T
, que sería compatible con la (T?, T) -> T
firma de ??
.
(x ? 3 : throw new Exception())
se reemplaza para fines de análisis con algo más parecido(x ? 3 : absurd(throw new Exception()))
?