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 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 denomina tipos nulos (a menudo expresados como A?
). La diferencia principal entre los tipos de opción y los tipos nulos es que los tipos de opción admiten anidación (por ejemplo, Maybe (Maybe String)
≠ Maybe String
), mientras que los tipos nulos no (por ejemplo, String??
= String?
).
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]
En Agda, el tipo de opción se nombra Maybe
con variantes nothing
y .just a
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 )
# incluye "share/atspre_staload.hats"fn show_value ( opt : Opción int ): cadena = case + opt of | None () => "Sin valor" | Some ( s ) => tostring_int simplementar 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
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
En F#, el tipo de opción se define como . [5]type 'a option = None | Some of 'a
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
En Haskell, el tipo de opción se define como . [6]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
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
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
En OCaml, el tipo de opción se define como . [7]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
En Rust, el tipo de opción se define como . [8]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
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
En ML estándar, 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 . [9]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 ? = nuloprint ( "mostrarValor(completo) -> \( mostrarValor ( completo )) " ) print ( "mostrarValor(vacío) -> \( mostrarValor ( vacío )) " )
showValue(full) -> El valor es: 42 showValue(empty) -> 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
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