구조형 시스템
Structural type system유형 시스템 |
---|
일반적인 개념 |
주요 카테고리 |
마이너 카테고리 |
구조형 시스템(또는 속성 기반 유형 시스템)은 형식 호환성과 동등성이 형식 이름이나 선언 장소와 같은 다른 특성이 아닌 형식의 실제 구조나 정의에 의해 결정되는 주요 유형 시스템 클래스입니다.구조 시스템은 유형이 동일한지, 유형이 다른 유형의 하위 유형인지 여부를 결정하기 위해 사용됩니다.이는 형식 또는 명시적 선언의 이름을 기반으로 비교되는 주격 시스템과 런타임에 액세스되는 구조의 일부만 호환성을 검사하는 덕 타이핑과 대조됩니다.
묘사
구조 타이핑에서 요소는 두 번째 요소의 유형 내의 각 특징에 대해 첫 번째 요소의 유형에 대응하는 동일한 특징이 존재하는 경우 다른 요소와 호환되는 것으로 간주됩니다.이름에 따라 기능이 일치해야 하는지 여부 등 세부 사항에 따라 언어가 다를 수 있습니다.이 정의는 대칭이 아니며 하위 유형 호환성을 포함합니다.두 가지 유형이 각각 다른 유형과 호환될 경우 동일한 것으로 간주됩니다.
예를 들어 OCaml은 객체 유형의 호환성을 위해 메서드에 구조 입력을 사용합니다.Go는 메서드에 구조 입력을 사용하여 인터페이스와의 유형의 호환성을 판단합니다.C++ 템플릿 함수는 타입 인수에 구조적인 타입을 나타냅니다.Haxe는 구조 유형을 사용하지만 클래스는 구조적으로 하위 유형이 아닙니다.
아형다형성을 지원하는 언어에서는 아형관계를 정의하는 방법에 따라 유사한 이분법을 형성할 수 있다.한 유형은 기본 유형의 모든 기능을 포함하는 경우에만 다른 유형의 하위 유형입니다.하위 유형에는 기본 유형에 없는 멤버 또는 더 강한 불변수와 같은 추가된 기능이 포함될 수 있습니다.
유추 다형과 비유도 다형의 구조적 치환 사이에는 차이가 존재한다.Haskell과 같은 일부 언어는 예상 유형이 선언된 경우 구조적으로 대체하지 않는다(예: 추론되지 않음). 예를 들어, 형식 [1]추론을 통해 시그니처 기반 다형성 함수만 대체한다.그 후, 암묵적으로 호출되는 비송신 타입으로의 명시적인 변환을 제공할 수 있지만, 실수로 비송신 타입의 서브 타입을 입력할 수는 없습니다.
구조 서브타이핑은 애드혹타입과 프로토콜의 생성을 허용하기 때문에 지정 서브타이핑보다 유연하다.특히, 후자의 정의를 수정하지 않고 기존 유형의 슈퍼타입인 유형을 생성할 수 있다.그러나 프로그래머가 폐쇄적인 추상화를 만들고자 하는 경우에는 바람직하지 않을 수 있습니다.
구조 유형 대 주격 유형의 함정은 서로 다른 목적을 위해 별도로 정의된 두 가지 유형이지만 우연히 동일한 특성(예: 둘 다 한 쌍의 정수로 구성됨)을 보유하는 것이 유형 시스템에 의해 동일한 유형으로 간주될 수 있다는 것이다. 단지 두 유형이 동일한 구조를 가지고 있기 때문이다.이를 피할 수 있는 한 가지 방법은 각 용도에 대해 하나의 대수 데이터 유형을 생성하는 것입니다.
1990년, 쿡 등은 유전이 구조적인 유형의 OO 언어로 [2]서브타이핑되지 않는다는 것을 증명했다.
구조 유형을 기반으로 두 유형이 호환되는지 확인하는 것은 간단한 작업이 아닙니다. 예를 들어, 이전에 검사한 [3]유형의 스택을 유지해야 합니다.
예
OCaml 내의 오브젝트는 메서드의 이름과 유형에 따라 구조적으로 입력됩니다.
오브젝트는 주격 클래스를 거치지 않고 직접(즉시 오브젝트) 작성할 수 있습니다.클래스는 개체를 만드는 함수 역할만 합니다.
# 허락하다 x = 물건 값 변이 가능한 x = 5 방법 get_x = x 방법 set_x y = x <-> y 끝.;; 값 x : < > get_x : 인트; set_x : 인트 -> 구성 단위 > = < >obj>
여기서 OCaml 인터랙티브 런타임은 편의를 위해 오브젝트의 추정 유형을 출력합니다.종류(< get_x : int; set_x : int -> unit >
)는 그 메서드에 의해서만 정의됩니다.즉, x의 유형은 임의의 이름이 아닌 [4]"get_x : int" 및 "set_x : int -> unit" 메서드유형으로 정의됩니다.
메서드 및 메서드 유형이 동일한 다른 개체를 정의하려면 다음 절차를 따릅니다.
# 허락하다 y = 물건 방법 get_x = 2 방법 set_x y = 프린트.인쇄물 %d\n" y 끝.;; 값 y : < > get_x : 인트; set_x : 인트 -> 구성 단위 > = < >obj>
OCaml은 이들을 같은 유형으로 간주합니다.예를 들어, 동일한 유형의 두 값만 가져오도록 equality 연산자를 입력합니다.
# x = y;; - : 부울 = 거짓의
그럼 같은 타입일 거야 그렇지 않으면 타이프체크도 안 될 거야이것은 유형의 동등성이 구조적이라는 것을 보여준다.
메서드를 호출하는 함수를 정의할 수 있습니다.
# 허락하다 10으로 설정 a = a#set_x 10;; 값 10으로 설정 : < > set_x : 인트 -> 'a; .. > -> 'a = < >재밌어요>
첫 번째 인수의 추론 유형(< set_x : int -> 'a; .. >
)는 흥미롭습니다.그..
첫 번째 인수는 int를 인수로 하는 "set_x" 메서드를 가진 임의의 오브젝트임을 의미합니다.
오브젝트에 사용할 수 있습니다.x
:
# 10으로 설정 x;; - : 구성 단위 = ()
그 메서드 및 메서드유형을 가진 다른 오브젝트를 만들 수 있습니다.다른 메서드는 관련이 없습니다.
# 허락하다 z = 물건 방법 부라부라 = 2.5 방법 set_x y = 프린트.인쇄물 %d\n" y 끝.;; 값 z : < > 부라부라 : 흘러가다; set_x : 인트 -> 구성 단위 > = < >obj>
"set_to_10" 함수도 작동합니다.
# 10으로 설정 z;; 10 - : 구성 단위 = ()
이는 메서드 호출 등의 호환성이 구조에 따라 결정된다는 것을 보여줍니다.
"get_x" 메서드만 사용하고 다른 메서드는 사용하지 않는 객체의 유형 동의어를 정의합니다.
# 유형 심플_obj = < > get_x : 인트 >;;; 유형 심플_obj = < > get_x : 인트 >
오브젝트x
이런 타입은 아니지만 구조적으로는x
이 유형의 하위 유형입니다.x
에는 메서드의 슈퍼셋이 포함되어 있습니다.그렇게x
는, 다음의 타입으로 강제할 수 있습니다.
# (x :> 심플_obj);; - : 심플_obj = < >obj> # (x :> 심플_obj)#get_x;; - : 인트 = 10
하지만 반대는 아니다.z
구조 서브타입이 아니기 때문에:
# (z:> simple_obj);;이 식은 simpler_obj = < get_x : int > 를 입력하도록 강제할 수 없습니다.유형은 < blahblah : float ; set_x : int - > 이지만, 여기서 사용되는 유형은 < get_x : int ; int ; 입니다.> 첫 번째 오브젝트 타입에는 메서드 get_x가 없습니다.
이는 강압 확대에 대한 양립가능성이 구조적이라는 것을 보여준다.
레퍼런스
- ^ "Signature-based polymorphism".
- ^ Cook, W.R.; Hill, W.L.; Canning, P.S. (January 1990). "Inheritance is not subtyping". Proceedings of the Seventeenth Annual ACM Symposium on Principles of Programming Languages. San Francisco, California: 125–135. doi:10.1145/96709.96721. ISBN 978-0897913430.
- ^ "Type compatibility: name vs structural equivalence".
- ^ "Object types".
- Pierce, Benjamin C. (2002). "19.3". Types and Programming Languages. MIT Press. ISBN 978-0-262-16209-8.
외부 링크
- WikiWiki Web에서의 Nominative AndStructural Typing