ADT, GADT 및 유도 유형의 차이점은 무엇입니까?


답변:


21

대수 데이터 유형을 사용하면 유형을 재귀 적으로 정의 할 수 있습니다. 구체적으로, 데이터 유형이 있다고 가정

datalist=Nil|ConsofN×list

이것은 가 및 연산자에 의해 생성 된 가장 작은 집합 이라는 것을 의미 합니다. 연산자 정의하여이를 공식화 할 수 있습니다.listNilConsF(X)

F(X)=={Nil}{Cons(n,x)|nNxX}

그런 다음 를 다음과 같이 정의하십시오.list

list=iNFi()

일반화 ADT는 타입 정의 할 때 우리가 무엇을 얻을 연산자를 재귀. 예를 들어 다음 유형 생성자를 정의 할 수 있습니다.

busha=Leafofa|Nestofbush(a×a)

이 유형 수단의 요소 것을 의 튜플이다 길이의 일부 , 각 시간 이후 우리가 들어갈 유형의 인수가 자체와 페어링되어 생성자 . 따라서 고정 소수점을 원하는 연산자를 다음과 같이 정의 할 수 있습니다.a 2 n n N e s tbushaa2nnNest

F(R)=λX.{Leaf(x)|xX}{Nest(v)|vR(X)}

Coq의 귀납적 유형은 본질적으로 GADT이며, 유형 연산자의 색인은 다른 유형 (예 : Haskell에서와 같이)으로 제한되지 않고 유형 이론의 으로 색인화 될 수도 있습니다 . 이를 통해 길이 인덱스 목록 등에 유형을 지정할 수 있습니다.


1
고맙습니다. 그러나 이것이 "종속적 유형"과 완전히 동의어 인 "유도 유형"을 의미하지 않습니까?
ninjagecko

4
@Neel : GADT와 같은 유형을 본 적이 없습니다 bush. 나는 그것들을 중첩 또는 비정규 유형이라고 불렀습니다.
jbapple

3
중첩 유형은 GADT의 특수한 경우입니다. GADT의 중요한 특징은 단순히 그것이 더 높은 종류의 재귀 적 정의라는 것입니다. (rhs의 변경은 기본적으로 생성자의 구성 요소로 형식 평등을 추가하기위한 구문 설탕입니다.)
Neel Krishnaswami

4
@ninjagecko : "유도 형"은 시맨틱이 생성자의 최소 고정 점으로 주어진 유형입니다. 모든 유형을 이러한 방식으로 설명 할 수있는 것은 아닙니다 (함수는 스트림과 같은 무한 유형도 불가능합니다). 종속 유형은 프로그램 용어가 해당 유형에서 발생할 수 있도록 허용하는 유형을 나타냅니다. Coq는 종속 유형 이론이므로 정의 할 수있는 유도 유형도 종속됩니다. 그러나 비 의존적 유형 이론은 귀납적 유형도 지원할 수 있으며, 이러한 귀납적 유형은 의존적이지 않습니다.
Neel Krishnaswami

2
@NeelKrishnaswami : 유형의 "처음 몇 개의 가장 작은"요소를 열거하여 답변을 명확하게 설명 하시겠습니까 bush a? 이 예에서 Nest Leaf(a) Leaf(a) Leaf(a) Leaf(a), 또는 Nest ((Nest Leaf(a) Leaf(a)) (Nest Leaf(a) Leaf(a)))세트의 한 예입니까?
ninjagecko

19

다음과 같은 대수 데이터 유형을 고려하십시오.

data List a = Nil | Cons a (List a)

데이터 유형에서 각 생성자의 반환 유형은 모두 동일 Nil하며 Cons모두 return List a입니다. 생성자가 다른 유형을 반환하도록 허용하면 GADT가 있습니다 .

data Empty -- this is an empty data declaration; Empty has no constructors
data NonEmpty

data NullableList a t where
    Vacant :: NullableList a Empty
    Occupied :: a -> NullableList a b -> NullableList a NonEmpty

Occupied유형이있는 a -> NullableList a b -> NullableList a NonEmpty반면 Cons유형이 a -> List a -> List a있습니다. 이 NonEmpty용어는 용어가 아니라 유형입니다. 또 다른 예:

data Zero
data Succ n

data SizedList a t where
    Alone :: SizedList a Zero
    WithFriends :: a -> SizedList a n -> SizedList a (Succ n)

종속 유형이있는 프로그래밍 언어의 유도 유형은 생성자의 리턴 유형이 인수의 값 (유형이 아닌)에 종속되도록합니다.

Inductive Parity := Even | Odd.

Definition flipParity (x:Parity) : Parity :=
  match x with
    | Even => Odd
    | Odd => Even
  end.

Fixpoint getParity (x:nat) : Parity :=
  match x with
    | 0 => Even
    | S n => flipParity (getParity n)
  end.

(*
A ParityNatList (Some P) is a list in which each member
is a natural number with parity P.
*)

Inductive ParityNatList : option Parity -> Type :=
  Nil : forall P, ParityNatList P
| Cons : forall (x:nat) (P:option Parity), 
  ParityNatList P -> ParityNatList 
  (match P, getParity x with
     | Some Even, Even => Some Even
     | Some Odd, Odd => Some Odd
     | _, _ => None
   end).

참고 사항 : GHC에는 값 생성자를 유형 생성자로 취급하는 메커니즘이 있습니다. 이는 Coq의 종속 유도 유형과 동일하지 않지만 GADT의 구문 부담을 다소 줄이고 오류 메시지를 개선 할 수 있습니다.


고맙습니다. "종속 유형이있는 프로그래밍 언어의 유도 유형" 그러면 종속 유형 이없는 언어에서 유도 유형은 어떻게 보이고 비유도 (그러나 GADT와 유사한) 종속 유형을 가질 수 있습니까?
ninjagecko
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.