En los lenguajes de programación (especialmente los lenguajes de programación funcionales ) y la teoría de tipos , un tipo de opción o quizás un tipo es un tipo polimórfico que representa la encapsulación de un valor opcional; por ejemplo, se utiliza como 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 None
o Nothing
) o que encapsula el tipo de datos original A
(a menudo escrito Just A
o Some A
).
Un concepto distinto, pero relacionado fuera de la programación funcional, que es popular en la programación orientada a objetos , se llama tipos que aceptan valores NULL (a menudo expresado como A?
). La principal diferencia entre los tipos de opciones y los tipos que aceptan valores NULL es que los tipos de opciones admiten el anidamiento (por ejemplo, Maybe (Maybe String)
≠ Maybe String
), mientras que los tipos que aceptan valores NULL no (por ejemplo, String??
= String?
).
En teoría de tipos , puede escribirse 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 opciones 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. [ ¿investigacion 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 realizar un seguimiento eficaz de fallos y errores. [3]
En Agda, el tipo de opción se nombra Maybe
con variantes nothing
y .just a
Desde C++ 17, el tipo de opción se define en la biblioteca estándar como .template<typename T> std::optional<T>
En Coq, el tipo de opción se define como .Inductive option (A:Type) : Type := | Some : A -> option A | None : option A.
En Elm, el tipo de opción se define como . [4]type Maybe a = Just a | Nothing
dejar mostrarValor = Opción . fold ( fun _ x -> sprintf "El valor es: %d" x ) "Sin valor" dejar lleno = Algunos 42 dejar vacío = Ninguno showValue lleno |> printfn "showValue lleno -> %s" showValue vacío |> printfn "showValue vacío -> %s"
showValue lleno -> El valor es: 42 showValue vacío -> Sin valor
En Haskell, el tipo de opción se define como . [5]data Maybe a = Nothing | Just a
showValue :: Quizás Int -> String showValue = foldl ( \ _ x -> "El valor es: " ++ show x ) "Sin valor" principal :: IO ( ) principal = dejar lleno = Solo 42 dejar vacío = Nada putStrLn $ "showValue completo -> " ++ showValue completo putStrLn $ "showValue vacío -> " ++ showValue vacío
showValue lleno -> El valor es: 42 showValue vacío -> Sin valor
En Idris, el tipo de opción se define como .data Maybe a = Nothing | Just a
showValue : Quizás Int -> String
showValue = foldl (\ _ , x => "El valor es " ++ show x ) "Sin valor" principal : IO ( )
principal = dejar lleno = Solo 42 dejar vacío = Nada putStrLn $ "showValue completo -> " ++ showValue completo putStrLn $ "showValue vacío -> " ++ showValue vacío
showValue lleno -> El valor es: 42 showValue vacío -> Sin valor
importar estándar / opciones proc showValue ( opt : Opción [ int ] ): cadena = opt . map ( proc ( x : int ): cadena = "El valor es: " & $ x ). obtener ( "Sin valor" ) dejar lleno = algunos ( 42 ) vacío = ninguno ( int ) echo "showValue(completo) -> " , showValue ( completo ) echo "showValue(vacío) -> " , showValue ( vacío )
showValue(completo) -> El valor es: 42 showValue(vacío) -> Sin valor
En OCaml, el tipo de opción se define como . [6]type 'a option = None | Some of 'a
let show_value = Opción . fold ~ none : "Sin valor" ~ some :( fun x -> "El valor es: " ^ string_of_int x )let () = let full = Unos 42 in let vacio = Ninguno en print_endline ( "mostrar_valor completo -> " ^ mostrar_valor completo ); print_endline ( "mostrar_valor vacio -> " ^ mostrar_valor vacio )
show_value completo -> El valor es: 42 show_value vacío -> Sin valor
En Rust, el tipo de opción se define como . [7]enum Option<T> { None, Some(T) }
fn show_value ( opt : Opción <i32> ) - > Cadena { opt . map_or ( "Sin valor" . to_owned (), | x | formato! ( "El valor es: {}" , x )) } fn main () { let full = Algunos ( 42 ); dejar vacío = Ninguno ; imprimir! ( "show_value(completo) -> {}" , show_value ( completo )); imprimir! ( "mostrar_valor (vacío) -> {}" , mostrar_valor ( vacío )); }
show_value(completo) -> El valor es: 42 show_value(vacío) -> Sin valor
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 ]): Cadena = opt . fold ( "Sin valor" )( x => s "El valor es: $ x " ) def main ( argumentos : Matriz [ Cadena ]): Unidad = val completo = Algunos ( 42 ) val vacío = Ninguno println ( s"mostrarValor(completo) -> ${ mostrarValor ( completo ) } " ) println ( s"mostrarValor(vacío) -> ${ mostrarValor ( vacío ) } " )
showValue(completo) -> El valor es: 42 showValue(vacío) -> Sin valor
En Standard ML, el tipo de opción se define como .datatype 'a option = NONE | SOME of 'a
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 ? ) -> Cadena { return opt . map { "El valor es: \( $0 ) " } ?? "Sin valor" } dejar lleno = 42 dejar vacío : Int ? = nuloprint ( "mostrarValor(completo) -> \( mostrarValor ( completo ) " ) imprimir ( "mostrarValor(vacío) -> \( mostrarValor ( vacío )) " )
showValue(completo) -> El valor es: 42 showValue(vacío) -> Sin valor
En Zig, agregue ? antes del nombre del tipo ?i32
para 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
const estándar = @import ( "estándar" ); fn showValue ( asignador : std . mem . Asignador , opt :? i32 ) ! [] u8 { regresar si ( optar ) | norte | estándar . fmt . allocPrint ( asignador , "El valor es: {}" , .{ n }) else asignador . engañar ( u8 , "Sin valor" ); } pub fn principal () ! void { // Configura un asignador y avisa si olvidamos liberar memoria. var gpa = estándar . montón . Asignador de uso general (.{}){}; aplazar estándar . depurar . afirmar ( gpa . deinit () == . ok ); asignador constante = gpa . asignador (); // Preparar el flujo de salida estándar. const salida estándar = estándar . yo . getStdOut (). escritor (); // Realiza nuestro ejemplo. constante completa = 42 ; constante vacío = nulo ; const full_msg = prueba showValue ( asignador , completo ); diferir el asignador . gratis ( msg_completo ); Pruebe la salida estándar . print ( "showValue(asignador, completo) -> {s} \n " , .{ full_msg }); const vacío_msg = prueba showValue ( asignador , vacío ); diferir el asignador . gratis ( mensaje_vacío ); Pruebe la salida estándar . print ( "showValue(asignador, vacío) -> {s} \n " , .{ mensaje_vacío }); }
showValue(asignador, completo) -> El valor es: 42 showValue(asignador, vacío) -> Sin valor