En los lenguajes de programación (especialmente los lenguajes de programación funcional ) y la teoría de tipos , un tipo de opción o tipo tal vez es un tipo polimórfico que representa la encapsulación de un valor opcional; por ejemplo, se utiliza como el tipo de retorno de funciones que pueden o no devolver un valor significativo cuando se aplican. Consiste en un constructor que está vacío (a menudo llamado Noneo Nothing), o que encapsula el tipo de datos original A(a menudo escrito Just Ao Some A).
Un concepto distinto, pero relacionado fuera de la programación funcional, que es popular en la programación orientada a objetos , se denomina tipos que aceptan valores nulos (a menudo expresados como A?). La diferencia principal entre los tipos de opción y los tipos que aceptan valores nulos es que los tipos de opción admiten anidación (por ejemplo, Maybe (Maybe String)≠ Maybe String), mientras que los tipos que aceptan valores nulos no (por ejemplo, String??= String?).
Aspectos teóricos
En teoría de tipos , se puede escribir como: . Esto expresa el hecho de que para un conjunto dado de valores en , un tipo de opción agrega exactamente un valor adicional (el valor vacío) al conjunto de valores válidos para . Esto se refleja en la programación por el hecho de que en los lenguajes que tienen uniones etiquetadas , los tipos de opción se pueden expresar como la unión etiquetada del tipo encapsulado más un tipo de unidad . [1]
En la correspondencia Curry-Howard , los tipos de opciones están relacionados con la ley de aniquilación para ∨: x∨1=1. [ ¿cómo? ]
Un tipo de opción también puede verse como una colección que contiene uno o cero elementos. [ ¿ Investigación original? ]
El tipo de opción también es una mónada donde: [2]
return = Just - Envuelve el valor en un tal vez
Nada >>= f = Nada -- Falla si la mónada anterior falla ( Solo x ) >>= f = f x -- Tiene éxito cuando ambas mónadas tienen éxito
La naturaleza monádica del tipo de opción es útil para rastrear de manera eficiente fallas y errores. [3]
Ejemplos
Agadé
En Agda, el tipo de opción se nombra Maybecon variantes nothingy .
just a
ATS
En ATS, el tipo de opción se define como
tipo de datos opción_t0ype_bool_type ( a : t @ ype +, bool ) =
| Algún ( a , verdadero ) de a
| Ninguno ( a , falso )
stadef opción = opción_t0ype_bool_type
typedef Opción ( a : t @ ype ) = [ b : bool ] opción ( a , b )
# incluir "share/atspre_staload.hats"
fn show_value ( opt : Opción int ): cadena =
case + opt of
| None () => "Sin valor"
| Some ( s ) => tostring_int s
implementar main0 () : void = let
val full = Some 42
y empty = None
en
println !( "mostrar_valor completo → " , mostrar_valor completo );
println !( "mostrar_valor vacío → " , mostrar_valor vacío );
fin
show_value completo → 42
show_value vacío → Sin valor
C++
Desde C++17, el tipo de opción se define en la biblioteca estándar como .
template<typename T> std::optional<T>
Gallo
En Coq, el tipo de opción se define como .
Inductive option (A:Type) : Type := | Some : A -> option A | None : option A.
Olmo
En Elm, el tipo de opción se define como . [4]type Maybe a = Just a | Nothing
F#
deje que showValue = Option . fold ( fun _ x -> sprintf "El valor es: %d" x ) "Sin valor"
deje lleno = Algunos 42 deje vacío = Ninguno
mostrarValor completo |> printfn "mostrarValor completo -> %s" mostrarValor vacío |> printfn "mostrarValor vacío -> %s"
showValue full -> El valor es: 42
showValue empty -> Sin valor
Haskell
En Haskell, el tipo de opción se define como . [5]data Maybe a = Nothing | Just a
showValue :: Maybe Int -> String showValue = foldl ( \ _ x -> "El valor es: " ++ show x ) "Sin valor"
principal :: IO () principal = do let full = Solo 42 let empty = Nada
putStrLn $ "mostrarValor completo -> " ++ mostrarValor completo putStrLn $ "mostrarValor vacío -> " ++ mostrarValor vacío
showValue full -> El valor es: 42
showValue empty -> Sin valor
Idris
En Idris, el tipo de opción se define como .
data Maybe a = Nothing | Just a
showValue : Maybe Int -> String
showValue = foldl (\ _ , x => "El valor es " ++ show x ) "Sin valor"
principal : IO ()
principal = hacer dejar lleno = Sólo 42 dejar vacío = Nada
putStrLn $ "mostrarValor completo -> " ++ mostrarValor completo
putStrLn $ "mostrarValor vacío -> " ++ mostrarValor vacío
showValue full -> El valor es: 42
showValue empty -> Sin valor
Nim
importar std / opciones
proc showValue ( opt : Option [ int ] ): string = opt.map ( proc ( x : int ) : string = "El valor es: " & $ x ) .get ( " Sin valor" )
deje
que lleno = algún ( 42 ) vacío = ninguno ( int )
echo "mostrarValor(completo) -> " , mostrarValor ( completo ) echo "mostrarValor(vacío) -> " , mostrarValor ( vacío )
showValue(full) -> El valor es: 42
showValue(empty) -> Sin valor
OCaml
En OCaml, el tipo de opción se define como . [6]type 'a option = None | Some of 'a
deje que show_value =
Option . fold ~ none : "Sin valor" ~ some :( fun x -> "El valor es: " ^ string_of_int x )
deje () =
deje lleno = Algunos 42 en
deje vacío = Ninguno en
print_endline ( "mostrar_valor completo -> " ^ mostrar_valor completo );
print_endline ( "mostrar_valor vacío -> " ^ mostrar_valor vacío )
show_value full -> El valor es: 42
show_value empty -> Sin valor
Óxido
En Rust, el tipo de opción se define como . [7]enum Option<T> { None, Some(T) }
fn show_value ( opt : Option < i32 > ) -> String {
opt.map_or ( "Sin valor" .to_owned ( ), | x | format ! ( "El valor es: {}" , x ) ) }
fn main () { deje que esté lleno = Algún ( 42 ); deje que esté vacío = Ninguno ;
println! ( "mostrar_valor(completo) -> {}" , mostrar_valor ( completo )); println! ( "mostrar_valor(vacío) -> {}" , mostrar_valor ( vacío )); }
show_value(full) -> El valor es: 42
show_value(empty) -> Sin valor
Escala
En Scala, el tipo de opción se define como , un tipo extendido por y .
sealed abstract class Option[+A]final case class Some[+A](value: A)case object None
objeto Principal : def showValue ( opt : Opción [ Int ]): String = opt.fold ( " Sin valor" )( x => s"El valor es : $ x " )
def main ( args : Matriz [ Cadena ]): Unidad = val lleno = Alguna ( 42 ) val vacío = Ninguno
println ( s"mostrarValor(completo) -> ${ mostrarValor ( completo ) } " )
println ( s"mostrarValor(vacío) -> ${ mostrarValor ( vacío ) } " )
showValue(full) -> El valor es: 42
showValue(empty) -> Sin valor
ML estándar
En ML estándar, el tipo de opción se define como .
datatype 'a option = NONE | SOME of 'a
Rápido
En Swift, el tipo de opción se define como pero generalmente se escribe como . [8]enum Optional<T> { case none, some(T) }T?
func showValue ( _opt : Int ?) -> String { return opt.map { " El valor es: \( $0 ) " } ?? " Sin valor" }
deje lleno = 42
deje vacío : Int ? = nulo
print ( "mostrarValor(completo) -> \( mostrarValor ( completo )) " )
print ( "mostrarValor(vacío) -> \( mostrarValor ( vacío )) " )
showValue(full) -> El valor es: 42
showValue(empty) -> Sin valor
Zig
En Zig, agregue ? antes del nombre del tipo ?i32para convertirlo en un tipo opcional.
La carga útil n se puede capturar en una declaración if o while , como , y se evalúa una cláusula else si es .
if (opt) |n| { ... } else { ... }null
constante estándar = @import ( "estándar" );
fn showValue ( allocator : std.mem.Allocator , opt : ? i32 ) ! [] u8 { return if ( opt ) | n | std.fmt.allocPrint ( allocator , " El valor es: { } " , . { n } ) else allocator.dupe ( u8 , " Sin valor " ) ; }
pub fn main () ! void { // Configurar un asignador y advertir si olvidamos liberar memoria. var gpa = std . heap . GeneralPurposeAllocator (.{}){}; defer std . debug . assert ( gpa . deinit () == . ok ); const allocator = gpa . allocator ();
// Preparar el flujo de salida estándar.
const stdout = std . io . getStdOut (). writer ();
// Ejecuta nuestro ejemplo.
const full = 42 ; const empty = null ;
const full_msg = try mostrarValor ( asignador , completo ); deferir asignador.free ( asignador , completo ); try stdout.print ( " mostrarValor (asignador, completo) -> {s} \ n " , .{ asignador, completo });
const empty_msg = try showValue ( allocator , empty ); defer allocator.free ( empty_msg ); try stdout.print ( "showValue ( allocator , empty) -> {s} \n " , . { empty_msg }) ; }
showValue(allocator, full) -> El valor es: 42
showValue(allocator, empty) -> Sin valor
Véase también
- Tipo de resultado
- Unión etiquetada
- Tipo que acepta valores NULL
- Patrón de objeto nulo
- Manejo de excepciones
- Coincidencia de patrones
Referencias
- ^ Milewski, Bartosz (13 de enero de 2015). "Tipos de datos algebraicos simples". Café de programación de Bartosz Milewski . Tipos de suma. "Podríamos haber codificado Maybe como: data Maybe a = Either () a". Archivado desde el original el 18 de agosto de 2019. Consultado el 18 de agosto de 2019 .
- ^ "Un puñado de mónadas: ¡aprenda Haskell para el bien común!". www.learnyouahaskell.com . Consultado el 18 de agosto de 2019 .
- ^ Hutton, Graham (25 de noviembre de 2017). "¿Qué es una mónada?". Computerphile Youtube . Archivado desde el original el 20 de diciembre de 2021. Consultado el 18 de agosto de 2019 .
- ^ "Tal vez · Una introducción a Elm". guide.elm-lang.org .
- ^ "6 tipos y clases predefinidos". www.haskell.org . Consultado el 15 de junio de 2022 .
- ^ "Biblioteca OCaml: Opción". v2.ocaml.org . Consultado el 15 de junio de 2022 .
- ^ "Opción en core::option - Rust". doc.rust-lang.org . 2022-05-18 . Consultado el 2022-06-15 .
- ^ "Documentación para desarrolladores de Apple". developer.apple.com . Consultado el 6 de septiembre de 2020 .