Tipo de opción

Encapsulación de un valor opcional en programación o teoría de tipos

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 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?).

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] A ? = A + 1 {\displaystyle A^{?}=A+1} A {\displaystyle A} A {\displaystyle A}

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 )
# 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

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#

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

Haskell

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

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 . [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

Óxido

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

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 . [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

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

Referencias

  1. ^ 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 .
  2. ^ "Un puñado de mónadas: ¡aprende a leer Haskell para el bien del bien!". www.learnyouahaskell.com . Consultado el 18 de agosto de 2019 .
  3. ^ 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 .
  4. ^ "Tal vez · Una introducción a Elm". guide.elm-lang.org .
  5. ^ "Opciones". fsharp.org . Consultado el 8 de octubre de 2024 .
  6. ^ "6 tipos y clases predefinidos". www.haskell.org . Consultado el 15 de junio de 2022 .
  7. ^ "Biblioteca OCaml: Opción". v2.ocaml.org . Consultado el 15 de junio de 2022 .
  8. ^ "Opción en core::option - Rust". doc.rust-lang.org . 2022-05-18 . Consultado el 2022-06-15 .
  9. ^ "Documentación para desarrolladores de Apple". developer.apple.com . Consultado el 6 de septiembre de 2020 .
Retrieved from "https://en.wikipedia.org/w/index.php?title=Option_type&oldid=1250166207"