Typ možnosti - Option type
Tento článek má několik problémů. Prosím pomozte zlepšit to nebo diskutovat o těchto otázkách na internetu diskusní stránka. (Zjistěte, jak a kdy tyto zprávy ze šablony odebrat) (Zjistěte, jak a kdy odstranit tuto zprávu šablony)
|
v programovací jazyky (více Funkcionální programování jazyky) a teorie typů, an typ možnosti nebo možná zadejte je polymorfní typ který představuje zapouzdření volitelné hodnoty; např. se používá jako návratový typ funkcí, které při použití mohou nebo nemusí vrátit smysluplnou hodnotu. Skládá se z konstruktoru, který je buď prázdný (často pojmenovaný Žádný
nebo Nic
), nebo který zapouzdřuje původní datový typ A
(často psáno Jen A
nebo Někteří A
).
Zřetelný, ale související koncept mimo funkční programování, který je populární v objektově orientované programování, je nazýván typy s možnou hodnotou Null (často vyjádřeno jako A?
). Základní rozdíl mezi typy možností a typy s možnou hodnotou Null je v tom, že typy možností podporují vnoření (Možná (možná A)
≠ Možná A.
), zatímco typy s možnou hodnotou Null ne (Tětiva??
= Tětiva?
).
Teoretické aspekty
Tato část má několik problémů. Prosím pomozte zlepšit to nebo diskutovat o těchto otázkách na internetu diskusní stránka. (Zjistěte, jak a kdy tyto zprávy ze šablony odebrat) (Zjistěte, jak a kdy odstranit tuto zprávu šablony)
|
v teorie typů, lze to napsat jako: . To vyjadřuje skutečnost, že pro danou sadu hodnot v , typ možnosti přidá do sady platných hodnot pro právě jednu další hodnotu (prázdnou hodnotu) . To se odráží v programování tím, že v jazycích, které mají označil odbory, typy možností lze vyjádřit jako tagované sjednocení zapouzdřeného typu plus a typ jednotky.[1]
V Curry – Howardova korespondence, typy možností se vztahují k zákon o zničení pro ∨: x∨1 = 1.[jak? ]
Typ možnosti lze také považovat za sbírka obsahující jeden nebo nula prvků.[původní výzkum? ]
Typ možnosti je také a monad kde:[2]
vrátit se = Prostě - Zabalí hodnotu do možnáNic >>= F = Nic - Selže, pokud selže předchozí monáda(Prostě X) >>= F = F X - Úspěch, když uspějí obě monády
Monadická povaha typu možnosti je užitečná pro efektivní sledování selhání a chyb.[3]
Názvy a definice
V různých programovacích jazycích má typ možnosti různé názvy a definice.
- v Agda, jmenuje se
Možná
s variantaminic
ajen a
. - v C ++ 17 je definována jako třída šablony
std::volitelný<T>
,volitelný()
lze použít k vytvoření prázdné možnosti. (Mohlo by se porušit monadové zákony kvůli silnému přetížení konstruktérů.) - v C#, je definován jako
Nullable<T>
ale obecně se píše jakoT?
. (Porušuje monadové zákony.) - v Coq, je definován jako
Induktivní volba (A:Typ) : Typ := | Nějaký : A -> volba A | Žádný : volba A.
. - v Jilm, jmenuje se
Možná
a definováno jakotyp Možná A = Prostě A | Nic
.[4] - v Haskell, jmenuje se
Možná
a definováno jakodata Možná A = Nic | Prostě A
. - v Idrisi, je definován jako
data Možná A = Nic | Prostě A
. - v Jáva od verze 8 je definována jako parametrizovaná finální třída
Volitelný<T>
. (Porušuje zákony monad (mapa je implementována nesprávně).) - v Julie, jmenuje se
Nullable{T}
. (To však již není podporováno.[5]) - v Kotlin, je definován jako
T?
.[6] (Porušuje zákony monad (nepodporuje vnoření).) - v OCaml, je definován jako
typ 'A volba = Žádný | Nějaký z 'A
. - v Perl 6, toto je výchozí nastavení, ale můžete přidat a
:D
„smajlík“, chcete-li se přihlásit k nepovinnému typu. (Porušuje zákony monad (nepodporuje vnoření.)) - v Rez, je definován jako
výčet Volba<T>{Žádný,Nějaký(T)}
. - v Scala, je definován jako
zapečetěný abstraktní třída Volba[+ A]
, typ rozšířený ofinále případ třída Nějaký[+ A](hodnota: A)
apřípad objekt Žádný
. - v Standardní ML, je definován jako
datový typ 'A volba = ŽÁDNÝ | NĚJAKÝ z 'A
. - v Rychlý, je definován jako
výčet Volitelný<T> { případ žádný, nějaký(T) }
ale obecně se píše jakoT?
.[7]
Příklady
Ada
Ada neimplementuje typy možností přímo, poskytuje však diskriminované typy, které lze použít k parametrizaci záznamu. K implementaci typu Option se jako diskriminační použije booleovský typ; následující příklad poskytuje obecný způsob vytvoření typu možnosti z libovolného neomezeného omezeného typu:
Obecný - Jakýkoli omezený a neomezený typ. Typ Typ prvku je soukromé;Balík Nepovinný_typ je - Když je diskriminující, Has_Element, pravdivý, existuje pole prvku, - pokud je nepravdivé, neexistují žádná pole (odtud klíčové slovo null). Typ Volitelný( Has_Element : Booleovský ) je záznam případ Has_Element je když Nepravdivé => Nula; když Skutečný => Živel : Typ prvku; konec případ; konečný záznam;konec Nepovinný_typ;
Scala
Scala nářadí Volba
jako parametrizovaný typ, takže proměnná může být Volba
, přístupné takto:[8]
objekt Hlavní { // Tato funkce používá porovnávání vzorů k dekonstruování možností def computeV1(opt: Volba[Int]): Tětiva = opt zápas { případ Nějaký(X) => s "Hodnota je: $ x" případ Žádný => "Bez ceny" } // Tato funkce používá integrovanou metodu `fold ' def computeV2(opt: Volba[Int]): Tětiva = opt.složit("Bez ceny")(X => s "Hodnota je: $ x") def hlavní(args: Pole[Tětiva]): Jednotka = { // Definujte proměnné, které jsou `Možnostmi typu` Int` val plný = Nějaký(42) val prázdný: Volba[Int] = Žádný // computeV1 (full) -> Hodnota je: 42 tisk(s "computeV1 (plný) ->${computeV1(plný)}") // computeV1 (prázdný) -> Žádná hodnota tisk(s "computeV1 (prázdný) ->${computeV1(prázdný)}") // computeV2 (full) -> Hodnota je: 42 tisk(s "computeV2 (plný) ->${computeV2(plný)}") // computeV2 (empty) -> Žádná hodnota tisk(s "computeV2 (prázdný) ->${computeV2(prázdný)}") }}
Dva hlavní způsoby použití Volba
hodnota existuje. První, ne nejlepší, je porovnávání vzorů, jako v prvním příkladu. Druhým nejlepším postupem je monadický přístup, jako v druhém příkladu. Tímto způsobem je program bezpečný, protože nemůže generovat žádnou výjimku ani chybu (např. Pokusem o získání hodnoty Volba
proměnná, která se rovná Žádný
). V podstatě tedy funguje jako typově bezpečná alternativa k hodnotě null.
OCaml
OCaml nářadí Volba
jako parametrizovaný typ varianty. Volba
s jsou konstruovány a dekonstruovány takto:
(* Tato funkce používá porovnávání vzorů k dekonstrukci možností *)nechat compute_v1 = funkce | Nějaký X -> „Hodnota je:“ ^ string_of_int X | Žádný -> "Bez ceny"(* Tato funkce používá vestavěnou funkci „skládání“ *)nechat compute_v2 = Volba.složit ~žádný:"Bez ceny" ~nějaký:(zábava X -> „Hodnota je:“ ^ string_of_int X)nechat () = (* Definujte proměnné, které jsou `možnostmi typu` int` *) nechat plný = Nějaký 42 v nechat prázdný = Žádný v (* compute_v1 full -> Hodnota je: 42 *) print_endline ("compute_v1 full ->" ^ compute_v1 plný); (* compute_v1 empty -> No value *) print_endline („compute_v1 empty ->“ ^ compute_v1 prázdný); (* compute_v2 full -> Hodnota je: 42 *) print_endline ("compute_v2 full ->" ^ compute_v2 plný); (* compute_v2 empty -> No value *) print_endline ("compute_v2 prázdný ->" ^ compute_v2 prázdný)
F#
// Tato funkce používá párování vzorů k dekonstruování možnostínechat compute_v1 = funkce | Nějaký X -> sprintf "Hodnota je:% d" X | Žádný -> "Bez ceny"// Tato funkce používá vestavěnou funkci `fold 'nechat compute_v2 = Volba.složit (zábava _ X -> sprintf "Hodnota je:% d" X) "Bez ceny"// Definujte proměnné, které jsou `možnostmi typu` int`nechat plný = Nějaký 42nechat prázdný = Žádný// compute_v1 full -> Hodnota je: 42compute_v1 plný |> printfn "compute_v1 full ->% s"// compute_v1 empty -> Žádná hodnotacompute_v1 prázdný |> printfn "compute_v1 prázdný ->% s"// compute_v2 full -> Hodnota je: 42compute_v2 plný |> printfn "compute_v2 full ->% s"// compute_v2 empty -> Žádná hodnotacompute_v2 prázdný |> printfn "compute_v2 prázdný ->% s"
Haskell
- Tato funkce používá porovnávání vzorů k dekonstrukci „Možná“computeV1 :: Možná Int -> TětivacomputeV1 (Prostě X) = „Hodnota je:“ ++ ukázat XcomputeV1 Nic = "Bez ceny"- Tato funkce používá vestavěnou funkci `foldl`computeV2 :: Možná Int -> TětivacomputeV2 = složit (_ X -> „Hodnota je:“ ++ ukázat X) "Bez ceny"hlavní :: IO ()hlavní = dělat - Definujte proměnné, které jsou `Možná typu Int nechat plný = Prostě 42 nechat prázdný = Nic - computeV1 full -> Hodnota je: 42 putStrLn $ "computeV1 full ->" ++ computeV1 plný - computeV1 full -> Žádná hodnota putStrLn $ "computeV1 empty ->" ++ computeV1 prázdný - computeV2 full -> Hodnota je: 42 putStrLn $ "computeV2 full ->" ++ computeV2 plný - computeV2 full -> Žádná hodnota putStrLn $ "computeV2 empty ->" ++ computeV2 prázdný
Rychlý
// Tato funkce používá příkaz `switch` k dekonstrukci argumentu` Optional`sfunc computeV1(_ opt: Int?) -> Tětiva { přepínač opt { případ .nějaký(nechat X): vrátit se "Hodnota je: (X)" případ .žádný: vrátit se "Bez ceny" }}// Tato funkce používá volitelnou vazbu k dekonstrukci `Volitelné`func computeV2(_ opt: Int?) -> Tětiva { -li nechat X = opt { vrátit se "Hodnota je: (X)" } jiný { vrátit se "Bez ceny" }}// Definujte proměnné, které jsou `Volitelné` typu` Int`nechat plný: Int? = 42nechat prázdný: Int? = nula// computeV1 (full) -> Hodnota je: 42tisk("computeV1 (plný) ->(computeV1(plný))")// computeV1 (prázdný) -> Žádná hodnotatisk("computeV1 (prázdný) ->(computeV1(prázdný))")// computeV2 (full) -> Hodnota je: 42tisk("computeV2 (plný) ->(computeV2(plný))")// computeV2 (empty) -> Žádná hodnotatisk("computeV2 (prázdný) ->(computeV2(prázdný))")
Rez
// Tato funkce používá výraz „shody“ k dekonstrukci možnostífn compute_v1(opt: &Volba<i32>)-> Tětiva {zápasopt{Nějaký(X)=>formát!(„Hodnota je: {}“,X),Žádný=>"Bez ceny".to_owned(),}}// Tato funkce používá výraz „if let“ k dekonstrukci možnostífn compute_v2(opt: &Volba<i32>)-> Tětiva {-linechatNějaký(X)=opt{formát!(„Hodnota je: {}“,X)}jiný{"Bez ceny".to_owned()}}// Tato funkce používá integrovanou metodu `map_or`fn compute_v3(opt: &Volba<i32>)-> Tětiva {opt.mapa_nebo("Bez ceny".to_owned(),|X|formát!(„Hodnota je: {}“,X))}fn hlavní(){// Definujte proměnné, které jsou `Možnostmi typu` i32`nechatplný=Nějaký(42);nechatprázdný: Volba<i32>=Žádný;// compute_v1 (& full) -> Hodnota je: 42tisk!(„compute_v1 (& full) -> {}“,compute_v1(&plný));// compute_v1 (& empty) -> Žádná hodnotatisk!(„compute_v1 (& empty) -> {}“,compute_v1(&prázdný));// compute_v2 (& full) -> Hodnota je: 42tisk!(„compute_v2 (& full) -> {}“,compute_v2(&plný));// compute_v2 (& empty) -> Žádná hodnotatisk!(„compute_v2 (& empty) -> {}“,compute_v2(&prázdný));// compute_v3 (& full) -> Hodnota je: 42tisk!(„compute_v3 (& full) -> {}“,compute_v3(&plný));// compute_v3 (& empty) -> Žádná hodnotatisk!(„compute_v3 (& empty) -> {}“,compute_v3(&prázdný))}
Nim
import možnosti# Tento proc používá vestavěné pro `isSome` a` get` pro dekonstrukciproc vypočítat(opt: Volba[int]): tětiva = -li opt.jeNěkdo: „Hodnota je:“ & $opt.dostat jiný: "Bez ceny"# Definujte proměnné, které jsou `Volitelné` typu` Int`nechat plný = nějaký(42) prázdný = žádný(int)# compute (full) -> Hodnota je: 42echo "výpočet (plný) ->", vypočítat(plný)# výpočet (prázdný) -> Žádná hodnotaecho "výpočet (prázdný) ->", vypočítat(prázdný)
Viz také
Reference
- ^ Milewski, Bartosz (2015-01-13). „Jednoduché algebraické datové typy“. Programovací kavárna Bartosze Milewského. Součet typů. "Mohli jsme zakódovat Možná jako: data Možná a = Either () a". Archivováno z původního dne 2019-08-18. Citováno 2019-08-18.
- ^ „Hrst monád - naučte se Haskell pro skvělé dobro!“. www.learnyouahaskell.com. Citováno 2019-08-18.
- ^ Hutton, Graham (25. listopadu 2017). „Co je to Monad?“. Počítačový soubor Youtube. Citováno 18. srpna 2019.
- ^ „Možná · Úvod do jilmu“. guide.elm-lang.org.
- ^ „Julia v0.7.0 - poznámky k verzi · Jazyk Julia“. docs.julialang.org.
- ^ "Nulová bezpečnost - programovací jazyk Kotlin". Citováno 2016-08-01.
- ^ „Dokumentace pro vývojáře Apple“. developer.apple.com. Citováno 2020-09-06.
- ^ Martin Oderský; Lex Spoon; Bill Venners (2008). Programování ve Scale. Artima Inc. str. 282–284. ISBN 978-0-9815316-0-1. Citováno 6. září 2011.