대수 데이터형
Algebraic data type![]() |
컴퓨터 프로그래밍, 특히 함수 프로그래밍과 유형 이론에서, 대수 데이터 유형(ADT)은 복합 유형의 일종이다. 즉, 다른 유형을 결합하여 형성된 유형이다.
대수 유형의 두 가지 공통 클래스는 제품 유형(즉, 튜플과 레코드)과 합계 유형(태그 부착 또는 분리 결합, 공동 생산 유형 또는 변형 유형)[1]이다.
제품 유형의 값에는 일반적으로 필드라는 여러 개의 값이 포함됩니다.그 형식의 모든 값 필드 형식의 같은 조합을 가지고 있습니다.제품 형식의 모든 가능한 값의 그 세트는set-theoretic 제품, 자신의 분야 유형의 모든 가능한 값의 그 세트의 즉, 데카르트 곱,.
얼마간 형식의 값 일반적으로는 몇몇 계급으로, 변형이라고 불리는 분류된다.는 변형 형식의 값은 보통quasi-functional 실체는 생성자 호출로 만들어진다.각 변수는 특정 종류와 논쟁의 지정된다는 자체 생성자, 가지고 있다.그것의 변형을 모든 가능한 값을 일련의 얼마간의 형식의 모든 가능한 값의 그 세트는set-theoretic 합, 즉 연결되지 않은 노조.와 정확히 하나의 값을 각 생성자에 대해 정의된 오른쪽 주행을 하는 생성자, 논쟁을 합 형태의Enumerated 장르는 특별 케이스다.
대수 유형의 값은 생성자 또는 필드 이름으로 값을 식별하고 포함하는 데이터를 추출하는 패턴 매칭으로 분석됩니다.
대수적 데이터형은 1970년대에 [2]에든버러 대학에서 개발된 작은 함수형 프로그래밍 언어인 Hope에서 도입되었다.
예
대수 데이터 유형의 가장 일반적인 예 중 하나는 단일 링크 리스트입니다.리스트 타입은 2개의 변형을 가진 합계 타입입니다.Nil
빈 리스트와Cons x xs
새 요소 x와 목록 xs를 조합하여 새 목록을 만듭니다.Haskell에서 단일 링크 리스트가 선언되는 예를 다음에 나타냅니다.
데이터. 목록. a = 제로 단점 a (목록. a)
또는
데이터. [] a = [] a : [a]
Cons
는 construct의 줄임말입니다.많은 언어에는 이렇게 정의된 목록에 대한 특별한 구문이 있습니다.예를 들어 Haskell과 ML은[]
위해서Nil
,:
또는::
위해서Cons
목록 전체에는 각 괄호를 사용합니다.그렇게Cons 1 (Cons 2 (Cons 3 Nil))
보통 이라고 쓰여진다1:2:3:[]
또는[1,2,3]
하스켈, 또는 로서1::2::3::[]
또는[1;2;3]
(ML)로 설정합니다.
조금 더 복잡한 예에서는 Haskell에서 다음과 같이 바이너리 트리를 구현할 수 있습니다.
데이터. 트리 = 빈 잎 내부 노드 트리 트리
또는
데이터. 바이너리 트리 a = BT닐 BTNode a (바이너리 트리 a) (바이너리 트리 a)
여기서,Empty
빈 트리를 나타냅니다.Leaf
데이터가 포함되어 있습니다.Node
는 데이터를 브랜치로 정리합니다.
대수적 데이터 유형을 지원하는 대부분의 언어에서는 파라메트릭 유형을 정의할 수 있습니다.이 글의 뒷부분에서 예를 제시하겠습니다.
함수와 다소 유사한 데이터 생성자는 적절한 유형의 인수에 적용되어 유형 생성자가 속한 데이터 유형의 인스턴스를 생성한다.예를 들어 데이터 생성자Leaf
논리적으로 함수입니다.Int -> Tree
즉, 인수로 정수를 지정한다.Leaf
유형의 값을 생성합니다.Tree
.~하듯이Node
두 가지 유형의 인수를 사용합니다.Tree
데이터형은 재귀적입니다.
대수 데이터형 연산은 패턴 매칭을 사용하여 인수를 검색함으로써 정의할 수 있습니다.예를 들어, 이 함수의 깊이를 구하는 함수를 생각해 봅시다.Tree
(여기 Haskell에서 제공):
깊이 :: 트리 -> 내부 깊이 빈 = 0 깊이 (잎 n) = 1 깊이 (노드 l r) = 1 + 맥스. (깊이 l) (깊이 r)
따라서,Tree
에 열중하는.depth
임의의 것을 사용하여 구성할 수 있다Empty
,Leaf
, 또는Node
모든 사건을 처리하려면 각각 일치해야 합니다.의 경우Node
패턴은 서브트리를 추출합니다.l
그리고.r
추가 처리를 위해.
대수 데이터 유형은 추상 구문 구현에 매우 적합합니다.예를 들어, 다음 대수 데이터 유형은 숫자 식을 나타내는 단순한 언어를 설명합니다.
데이터. 표현 = 번호 내부 더하다 표현 표현 마이너스 표현 표현 멀티 표현 표현 나누다 표현 표현
이러한 데이터 유형의 요소는 다음과 같은 형식을 가집니다.Mult (Add (Number 4) (Minus (Number 0) (Number 1))) (Number 2)
.
이 언어에 대한 평가 함수를 작성하는 것은 간단한 연습이지만, 보다 복잡한 변환도 실현 가능하게 됩니다.예를 들어, 컴파일러의 최적화 패스는 추상 표현을 입력으로 하여 최적화된 형식을 반환하는 함수로 작성될 수 있습니다.
설명.
몇 가지 유형 중 하나가 될 수 있는 데이터 유형이 있습니다.각 유형의 사물은 컨스트럭터라고 불리는 식별자와 관련지어지며, 이러한 데이터에는 일종의 태그로 볼 수 있습니다.각 생성자는 서로 다른 유형의 데이터를 운반할 수 있습니다.생성자는 어떤 데이터(예: 위의 예에서는 "빈"), 하나의 데이터(예: "리프"에는 하나의 Int 값이 있음) 또는 여러 데이터 조각(예: "노드"에는 두 개의 트리 값이 있음)을 전달할 수 없습니다.
이 트리 대수 데이터 유형의 값으로 작업을 수행하기 위해 패턴 매칭이라고 하는 프로세스를 사용하여 데이터를 디컨피규레이션합니다.여기에는 데이터를 일련의 패턴과 일치시키는 작업이 포함됩니다.위의 예제 함수 "depth"는 인수를 3가지 패턴으로 일치시킵니다.함수가 호출되면 해당 인수에 일치하는 첫 번째 패턴을 찾아 해당 패턴에서 발견된 변수 바인딩을 수행하고 패턴에 대응하는 식을 평가합니다.
위의 각 패턴은 이 데이터 유형의 가능한 값 구조와 유사한 형태를 가집니다.첫 번째 패턴은 단순히 생성자 Empty 값과 일치합니다.두 번째 패턴은 생성자 리프 값과 일치합니다.패턴은 재귀적이므로 해당 생성자와 연결된 데이터가 패턴 "n"과 일치합니다.이 경우 소문자 식별자는 임의의 값과 일치하는 패턴을 나타냅니다.이 경우 소문자 식별자는 해당 이름의 변수(이 경우 변수 "n
" 는 데이터 유형에 저장된 정수 값에 바인딩되어 있습니다.이 값은 평가할 식에서 사용됩니다.
이 예에서 패턴의 재귀는 사소한 것이지만 더 복잡한 재귀 패턴은 다음과 같습니다.
여러 레이어 깊이의 재귀 패턴은 예를 들어 빨간색과 검은색 트리의 균형을 맞추는 데 사용됩니다. 이 경우 여러 레이어 깊이의 색상을 검토해야 합니다. Node (Node (Leaf 4) x) (Node y (Node Empty z))
위의 예는 동작상 다음 의사 코드에 해당합니다.
전환하다 에 (데이터..생성자) 사례. 빈: 돌아가다 0 사례. 잎: 허락하다 n = 데이터..필드 1 돌아가다 1 사례. 노드: 허락하다 l = 데이터..필드 1 허락하다 r = 데이터..필드2 돌아가다 1 + 맥스. (깊이 l) (깊이 r)
이것을 패턴 매칭과 비교함으로써 대수적 데이터 유형과 패턴 매칭의 장점을 몇 가지 알 수 있을 것이다.첫 번째 장점은 형식 안전입니다.예를 들어, 위 의사 코드는 생성자가 리프일 때 접근하지 않는 프로그래머의 부지런함에 의존합니다.또한 의 유형은 리프 및 노드에 따라 다르기 때문에(리프의 경우 이며 노드의 경우 이 경우), 유형 시스템은 기존의 레코드 데이터 구조에서 정적 유형을 안전하게 할당하는 데 어려움이 있습니다.그러나 패턴 매칭에서는 해당 생성자가 선언한 유형에 따라 추출된 각 값의 종류를 체크하고 생성자에 따라 추출 가능한 값의 수를 알 수 있으므로 이러한 문제에 직면하지 않는다.
둘째, 패턴 매칭에서 컴파일러는 모든 케이스가 처리되었는지 정적으로 확인합니다.위의 깊이 함수 중 하나가 누락되면 컴파일러는 케이스가 처리되지 않음을 나타내는 경고를 보냅니다.이 작업은 위의 단순한 패턴에서는 쉬워 보일 수 있지만, 복잡한 재귀 패턴이 많기 때문에 평균적인 인간(또는 컴파일러, 임의의 중첩 if-else 구조를 확인해야 하는 경우)이 처리하기가 어려워집니다.마찬가지로 일치하지 않는 패턴이 있을 수 있습니다(즉, 이전 패턴에 이미 포함되어 있습니다).또한 컴파일러는 이러한 패턴을 체크하여 경고를 발행할 수 있습니다.이는 추론의 오류를 나타낼 수 있기 때문입니다.
이러한 패턴을 문자열 패턴 매칭에 사용되는 정규 표현 패턴과 혼동하지 마십시오.목적은 비슷합니다.데이터가 특정 제약조건과 일치하는지 확인하고 일치할 경우 관련 부분을 추출하여 처리하는 것입니다.하지만 메커니즘은 매우 다릅니다.대수 데이터 타입에 대한 이러한 패턴 매칭은 문자열의 문자열 시퀀스가 아닌 객체의 구조적 특성에 일치합니다.
이론.
일반 대수 데이터형은 곱 유형의 재귀적합 유형일 수 있습니다.각 생성자는 제품 유형에 태그를 지정하여 다른 생성자와 구분합니다. 생성자가 하나뿐인 경우 데이터 유형은 제품 유형입니다.또한 컨스트럭터의 파라미터 타입은 제품 타입의 요인이다.매개 변수가 없는 생성자는 빈 제품에 해당합니다.데이터 유형이 재귀적인 경우 제품의 전체 합계가 재귀 유형으로 래핑되고 각 생성자가 데이터 유형을 재귀 유형으로 롤링합니다.
예를 들어 Haskell 데이터 유형:
데이터. 목록. a = 제로 단점 a (목록. a)
는 에서 (i n ){ \ { } { \ { \ } = \ { } \ mathrm { } \ mathrm { l \ } \ { l } )로 표현된다 , {\ ( \ display \{ } _ { \ alpha \ x= \ \ ( \ { inr \ \ \ \ \ \ l \ )。
Haskell List 데이터형은 유형 이론에서도 약간 다른 형태로 수 있습니다. 즉, μ . . 、 . +α × \ \+ \ \ \ \ ( \ myle \ \ mu \ ) 。원래 형식에서는 본문이 재귀 형식인 형식 함수를 지정했습니다.수정된 버전은 유형에 대한 재귀 함수를 지정합니다.( { }는 그리스어 f와 같기 때문에β { 와 기본유형이 아닌 함수를 제안하기 위해 사용됩니다.)여기서 함수는 유형 본문의 인수 에도 되어야 합니다
목록 예제의 목적상, 이 두 공식은 크게 다르지 않습니다.그러나 두 번째 형식은 소위 중첩된 데이터 유형, 즉 재귀 유형이 원본과 파라미터적으로 다른 데이터 유형을 표현할 수 있습니다( 중첩된 데이터 유형에 대한 자세한 내용은 Richard Bird, Lambert Meertens 및 Ross Paterson의 작업을 참조하십시오..)
집합론에서, 총합형에 상당하는 것은 분리된 결합이며, 그 요소는 태그(생성자와 동등)와 태그(생성자 인수와 동등)에 대응하는 타입의 오브젝트로 이루어진 쌍이다.
대수 데이터 유형을 사용하는 프로그래밍 언어
다음을 포함한 많은 프로그래밍 언어는 대수 데이터 유형을 퍼스트 클래스 개념으로 통합합니다.
「 」를 참조해 주세요.
레퍼런스
- ^ 기록 및 변형 - OCaml 설명서 섹션 1.4 웨이백 기계에 보관된 2020-04-28
- ^ Paul Hudak; John Hughes; Simon Peyton Jones; Philip Wadler. "A history of Haskell: being lazy with class". Proceedings of the third ACM SIGPLAN conference on History of programming languages.
Presentations included Rod Burstall, Dave MacQueen, and Don Sannella on Hope, the language that introduced algebraic data types
- ^ 귀납구조의 미적분, 기본 표준 라이브러리 : 및.
- ^ "CppCon 2016: Ben Deane "Using Types Effectively"". Archived from the original on 2021-12-12 – via www.youtube.com.
- ^ "Algebraic Data Types in Haskell". Serokell.
- ^ "Enum Instance". Haxe - The Cross-platform Toolkit.
- ^ "JEP 360: Sealed Classes (Preview)". OpenJDK.
- ^ "Sealed Classes - Kotlin Programming Language". Kotlin.
- ^ "Reason · Reason lets you write simple, fast and quality type safe code while leveraging both the JavaScript & OCaml ecosystems". reasonml.github.io.
- ^ "Enums and Pattern Matching - The Rust Programming Language". doc.rust-lang.org. Retrieved 31 August 2021.