옵션종류
Option type![]() |
프로그래밍 언어(특히 기능 프로그래밍 언어)와 유형 이론에서 옵션 유형 또는 유형 유형은 옵션 값의 캡슐화를 나타내는 다형성 유형이다. 예를 들어, 기능 반환 유형으로서 기능들이 적용될 때 의미 있는 값을 반환하거나 반환하지 않을 수 있다. 비어 있는 생성자(흔히 이름이 지정됨)로 구성된다. None
또는 Nothing
) 또는 원본 데이터 유형을 캡슐화하는 방법 A
(문자필기재) Just A
또는 Some A
).
객체 지향 프로그래밍에서 인기 있는 기능 프로그래밍 이외의 구별되지만 관련 개념은 nullable type(종종 nullable type)이라고 한다. A?
옵션 유형과 nullable 유형의 핵심 차이는 옵션 유형이 중첩을 지원한다는 것이다.Maybe (Maybe A)
≠ Maybe A
), nullable type은 그렇지 않지만 (String??
= String?
).
이론적 측면
![]() |
형식 이론에서는 과 같이쓸 있다 ? = A + 1 {\ A} 이것은 의 주어진 값 집합에대해 옵션 유형이 A 의 유효한 값 집합에 정확히 하나의 추가 값(빈 값)을 더한다는 사실을 나타낸다 이는 태그가 있는 언어에서 옵션 유형을 태그가 있는 조합으로 표시할 수 있다는 사실에 의해 프로그래밍에 반영된다. 캡슐화된 형식에 단위 형식을 더한다.[1]
Curry-Howard 통신에서 옵션 유형은 ∨: x∨1=1의 소멸 법칙과 관련이 있다.[how?]
옵션 유형은 1개 또는 0개 요소를 포함하는 집합으로도 볼 수 있다.[original research?]
돌아오다 = 그냥 -- 값을 아마추어로 포장 아무 것도 없어요. >>= f = 아무 것도 없어요. -- 이전 모나드가 실패할 경우 실패함 (그냥 x) >>= f = f x -- 두 모나드가 모두 성공할 때 성공
옵션 유형의 단색성은 오류와 오류를 효율적으로 추적하는 데 유용하다.[3]
이름 및 정의
다른 프로그래밍 언어에서 옵션 유형은 다양한 이름과 정의를 가지고 있다.
- 아그다에서는 이름이 붙여졌다.
Maybe
변형하여nothing
그리고just a
. - C++17에서는 템플릿 클래스로 정의된다.
std::optional<T>
,optional()
빈 옵션을 만드는 데 사용할 수 있다. (시공자의 과부하로 인해 모나드 법을 어길 수 있다.) - C#에서는 다음과 같이 정의된다.
Nullable<T>
그러나 일반적으로 다음과 같이 쓰여 있다.T?
. (모나드 법칙을 깨뜨린다.) - Coq에서는 다음과 같이 정의된다.
Inductive option (A:Type) : Type := Some : A -> option A None : option A.
. - 엘름에서는 이 이름이 붙여졌다.
Maybe
, 그리고 로 정의된다.type Maybe a = Just a Nothing
.[4] - 하스켈에서는 이 이름이 붙여졌다.
Maybe
, 그리고 로 정의된다.data Maybe a = Nothing Just a
. - 이드리스에서는 다음과 같이 정의된다.
data Maybe a = Nothing Just a
. - Java에서는 버전 8 이후 파라미터화된 최종 클래스로 정의된다.
Optional<T>
. (모나드 법칙을 깨뜨림(지도는 잘못 구현됨)[further explanation needed] - 줄리아에서는 이름이 지어졌다.
Nullable{T}
. (그러나, 이것은 더 이상 사용되지 않았다.)[5] - OCaml에서는 다음과 같이 정의된다.
type 'a option = None Some of 'a
. - Perl 6에서는 이 값이 기본값이지만 다음 값을 추가할 수 있다.
:D
비옵션 유형을 선택하기 위한 "smiley". (모나드 법률 위반(내포 지원 안 함) - 러스트에서는 다음과 같이 정의된다.
enum Option<T> { None, Some(T) }
. - 스칼라에서는 다음과 같이 정의된다.
sealed abstract class Option[+A]
, 확장된 형식final case class Some[+A](value: A)
그리고case object None
. - 표준 ML에서는 다음과 같이 정의된다.
datatype 'a option = NONE SOME of 'a
. - Swift에서는 다음과 같이 정의된다.
enum Optional<T> { case none, some(T) }
그러나 일반적으로 다음과 같이 쓰여 있다.T?
.[6]
예
에이다
Ada는 옵션 유형을 직접 구현하지는 않지만, 레코드를 매개변수로 지정하는 데 사용할 수 있는 차별적인 유형을 제공한다. 옵션 유형을 구현하기 위해 부울 유형을 판별로 사용하며, 다음 예에서는 제한되지 않은 제약 조건이 없는 유형에서 옵션 유형을 생성하기 위한 일반 형식을 제공한다.
포괄적인 -- 모든 제약 및 비제한 유형. 유형 요소_유형 이다 사유의; 패키지 선택적_유형 이다 -- 차별성 Has_Element가 참일 때 요소 필드가 있으면 -- false일 때는 필드가 없다(null 키워드 표시). 유형 선택적( Has_Element : 부울 ) 이다 기록하다 케이스 Has_Element 이다 할 때 거짓의 => Null; 할 때 진실의 => 요소 : 요소_유형; 종지부를 찍다 케이스; 기록을 끝내다; 종지부를 찍다 선택적_유형;
스칼라
스칼라 기구 Option
매개변수화된 유형으로, 따라서 변수는 Option
, 액세스 권한은 다음과 같다.[7]
이의를 제기하다 메인 { // 패턴 매칭을 사용하여 '옵션'을 해체하는 기능 반항하다 computeV1(선택하다: 옵션[인트]): 끈 = 선택하다 짝을 맞추다 { 케이스 일부(x) => s"값은: $x" 케이스 없음 => "값 없음" } // 내장된 '폴드' 방식을 사용하는 기능 반항하다 computeV2(선택하다: 옵션[인트]): 끈 = 선택하다.접다("값 없음")(x => s"값은: $x") 반항하다 본래의(아그: 배열[끈]): 구성 단위 = { // "Int" 유형의 "옵션" 변수 정의 발랄하게 하다 가득 찬 = 일부(42) 발랄하게 하다 텅 빈: 옵션[인트] = 없음 // computeV1(full) -> 값은: 42 인쇄하다(s"computeV1(full) -> ${computeV1(가득 찬)}") // 계산V1(비어 있음) -> 값 없음 인쇄하다(s"computeV1(비어 있음) -> ${computeV1(텅 빈)}") // computeV2(full) -> 값은: 42 인쇄하다(s"computeV2(full) -> ${computeV2(가득 찬)}") // 계산V2(비어 있음) -> 값 없음 인쇄하다(s"computeV2(빈) -> ${computeV2(텅 빈)}") } }
두 가지 주요 사용 방법 Option
가치가 있다 최고가 아닌 첫 번째는 첫 번째 예에서처럼 패턴 매칭이다. 두 번째, 가장 좋은 방법은 두 번째 예에서와 같이 단조로운 접근이다. 이러한 방법으로 프로그램은 예외나 오류를 발생시킬 수 없으므로(예를 들어, a의 값을 얻으려고 노력함으로써) 안전하다. Option
와 같은 변수 None
따라서 본질적으로 null 값에 대한 형식 안전 대안으로 작용한다.
OCAML
OCaml 구현 Option
매개 변수화된 변형 유형으로. Option
s는 다음과 같이 구성 및 해체된다.
* 패턴 매칭을 사용하여 '옵션'을 분해하는 기능 *) 하게 하다 compute_v1 = 기능을 하다 일부 x -> "값은: "이다. ^ string_of_int x 없음 -> "값 없음" (* 이 함수는 내장 '폴드' 함수를 사용함 *) 하게 하다 compute_v2 = 옵션.접다 ~없는:"값 없음" ~약간의:(재미있다 x -> "값은: "이다. ^ string_of_int x) 하게 하다 () = (* 유형 'int'의 '옵션'인 변수 정의 *) 하게 하다 가득 찬 = 일부 42 에 하게 하다 텅 빈 = 없음 에 (* compute_v1 full -> 값은 42 *) print_endline ("compute_v1 가득차 -> " ^ compute_v1 가득 찬); (* compute_v1 empty -> No value *) print_endline ("compute_v1 비어 있음 -> " ^ compute_v1 텅 빈); (* compute_v2 full -> 값은 42 *) print_endline ("compute_v2 가득차 -> " ^ compute_v2 가득 찬); (* compute_v2 empty -> No value *) print_endline ("compute_v2 empty -> " ^ compute_v2 텅 빈)
F#
// 패턴 매칭을 사용하여 '옵션'을 분해하는 기능 하게 하다 compute_v1 = 기능을 하다 일부 x -> 단거리 경주 "값: %d" x 없음 -> "값 없음" // 내장된 '폴드' 기능을 사용하는 기능 하게 하다 compute_v2 = 옵션.접다 (재미있다 _ x -> 단거리 경주 "값: %d" x) "값 없음" // '옵션' 유형인 변수 정의 하게 하다 가득 찬 = 일부 42 하게 하다 텅 빈 = 없음 // compute_v1 full -> 값은 42이다. compute_v1 가득 찬 > 인쇄하다 "192_v1 가득 참 -> %s" // compute_v1 비어 있음 -> 값 없음 compute_v1 텅 빈 > 인쇄하다 "1987_v1 비어 있음 -> %s" // compute_v2 full -> 값은 42이다. compute_v2 가득 찬 > 인쇄하다 "192_v2 가득 참 -> %s" // compute_v2 비어 있음 -> 값 없음 compute_v2 텅 빈 > 인쇄하다 "compute_v2 비어 있음 -> %s"
하스켈
-- 이 기능은 패턴 매칭을 사용하여 아마추어의 구조를 해체하는 기능이다. computeV1 :: 어쩌면 인트 -> 끈 computeV1 (그냥 x) = "값은: "이다. ++ 보여 주다 x computeV1 아무 것도 없어요. = "값 없음" -- 내장 '폴드' 기능을 사용하는 기능 computeV2 :: 어쩌면 인트 -> 끈 computeV2 = 접다 (\_ x -> "값은: "이다. ++ 보여 주다 x) "값 없음" 본래의 :: IO () 본래의 = 하다 -- 아마도 유형인 "Int"의 변수 정의 하게 하다 가득 찬 = 그냥 42 하게 하다 텅 빈 = 아무 것도 없어요. -- computeV1 full -> 값은: 42 putStrLn $ "computeV1 full ->" ++ computeV1 가득 찬 -- computeV1 full -> 값 없음 putStrLn $ "computeV1 empty -> " ++ computeV1 텅 빈 -- computeV2 full -> 값은: 42 putStrLn $ "computeV2 full ->" ++ computeV2 가득 찬 -- computeV2 full -> 값 없음 putStrLn $ "computeV2 empty -> " ++ computeV2 텅 빈
스위프트
// 이 함수는 'switch' 문을 사용하여 'Option'을 분해한다. 펑크 computeV1(_ 선택하다: 인트?) -> 끈 { 바꾸다 선택하다 { 케이스 .약간의(하게 하다 x): 돌아오다 "가치는 다음과 같다. \(x)" 케이스 .없는: 돌아오다 "값 없음" } } // 이 함수는 선택적 바인딩을 사용하여 '선택적'을 분해한다. 펑크 computeV2(_ 선택하다: 인트?) -> 끈 { 만일 하게 하다 x = 선택하다 { 돌아오다 "가치는 다음과 같다. \(x)" } 다른 { 돌아오다 "값 없음" } } // "Int" 유형의 "옵션" 하게 하다 가득 찬: 인트? = 42 하게 하다 텅 빈: 인트? = 못을 박다 // computeV1(full) -> 값은: 42 인쇄하다("computeV1(full) -> \(computeV1(가득 찬))") // 계산V1(비어 있음) -> 값 없음 인쇄하다("computeV1(비어 있음) -> \(computeV1(텅 빈))") // computeV2(full) -> 값은: 42 인쇄하다("computeV2(full) -> \(computeV2(가득 찬))") // 계산V2(비어 있음) -> 값 없음 인쇄하다("computeV2(비어 있음) -> \(computeV2(텅 빈))")
녹
// 이 함수는 "match" 식을 사용하여 "Option"의 fn compute_v1(opt: &Option<i32) -> 문자열 {match option { Some(x) => 형식!("값: {}", x), 없음 => "값 없음".to_소유(), } // 이 함수는 if let 식을 사용하여 option's fn compute_v2(opt: &Option<i32) -> 문자열 {만약 일부(x) = option { format!("값: {}", x) 다른 { "값 없음".to_소유() } } // 이 함수는 내장된 'map_or' 메서드 fn compute_v3(opt: &Option<i32) -> 문자열 {opt.map_or("No value")를 사용한다.to_소유 x 형식!("값: {}", x) } fn main() {/ i32의 "옵션" 유형인 변수 정의 full = 일부(42); let lete: lete: lete: lete: lete: lete: option<i32> = None; // comput_v1(&full) -> 값: 42 println!("compute_v1(&full) -> {}", compute_v1(&full); // compute_v1(&empty) -> 값 인쇄 없음!("compute_v1(&empty) -> {}", compute_v1(&empty); // compute_v2(&full) -> 값: 42 println!("compute_v2(&full) -> {}", compute_v2(&full); // compute_v2(&empty) -> 값 인쇄 없음!("compute_v2(&empty) -> {}", compute_v2(&empty); // compute_v3(&full) -> 값: 42 println!("compute_v3(&full) -> {}", compute_v3(&full); // compute_v3(&empty) -> 값 인쇄 없음!("compute_v3(&compute) -> {}", compute_v3(&compute) }
님
수입하다 옵션들 # 이 proc는 내장된 isSome과 get procs를 이용해 옵션의 구조를 해체한다. 생식을 하다 계산하다(선택하다: 옵션[인트로]): 끈을 매다 = 만일 선택하다.잇썸: "더 밸류: " & $선택하다.얻다 다른: "값 없음" # 유형별 옵션인 변수 정의 하게 하다 가득 찬 = 약간의(42) 텅 빈 = 없는(인트로) # 계산(완전) -> 값: 42 메아리치다 "compute(완전) -> ", 계산하다(가득 찬) # 계산(빈) -> 값 없음 메아리치다 "compute(empty) -> ", 계산하다(텅 빈)
참고 항목
참조
- ^ Milewski, Bartosz (2015-01-13). "Simple Algebraic Data Types". Bartosz Milewski's Programming Cafe. Sum types. "We could have encoded Maybe as: data Maybe a = Either () a". Archived from the original on 2019-08-18. Retrieved 2019-08-18.
- ^ "A Fistful of Monads - Learn You a Haskell for Great Good!". www.learnyouahaskell.com. Retrieved 2019-08-18.
- ^ Hutton, Graham (Nov 25, 2017). "What is a Monad?". Computerphile Youtube. Archived from the original on 2021-12-20. Retrieved Aug 18, 2019.
- ^ "Maybe · An Introduction to Elm". guide.elm-lang.org.
- ^ "Julia v0.7.0 Release Notes · The Julia Language". docs.julialang.org.
- ^ "Apple Developer Documentation". developer.apple.com. Retrieved 2020-09-06.
- ^ Martin Odersky; Lex Spoon; Bill Venners (2008). Programming in Scala. Artima Inc. pp. 282–284. ISBN 978-0-9815316-0-1. Retrieved 6 September 2011.