ADT, GADTs และอุปนัยประเภทต่างกันอย่างไร


21

ใคร ๆ ก็สามารถอธิบายความแตกต่างระหว่าง:

  • ประเภทข้อมูลพีชคณิต (ซึ่งฉันคุ้นเคยกับ)
  • ประเภทข้อมูลพีชคณิตทั่วไป (สิ่งที่ทำให้พวกเขา generalized?)
  • ประเภทอุปนัย (เช่น Coq)

(โดยเฉพาะอย่างยิ่งอุปนัยประเภท) ขอบคุณ

คำตอบ:


21

ชนิดข้อมูลเชิงพีชคณิตช่วยให้คุณกำหนดชนิดแบบเรียกซ้ำได้ แน่นอนว่าเรามีประเภทข้อมูล

daเสื้อaล.ผมsเสื้อ=ยังไม่มีข้อความผมล.|Cโอnsโอยังไม่มีข้อความ×ล.ผมsเสื้อ

สิ่งที่หมายถึงนี้ก็คือว่าเป็นชุดที่เล็กที่สุดที่สร้างขึ้นโดยไม่มีฉันลิตรและC o n sผู้ประกอบการ เราสามารถทำให้เป็นทางการได้โดยการกำหนดโอเปอเรเตอร์F ( X )ล.ผมsเสื้อยังไม่มีข้อความผมล.CโอnsF(X)

F(X)=={ยังไม่มีข้อความผมล.}{Cโอns(n,x)|nยังไม่มีข้อความxX}

แล้วกำหนดเป็นล.ผมsเสื้อ

ล.ผมsเสื้อ=ผมยังไม่มีข้อความFผม()

ทั่วไป ADT คือสิ่งที่เราได้รับเมื่อกำหนดประเภทผู้ประกอบการซ้ำ ตัวอย่างเช่นเราอาจกำหนดตัวสร้างประเภทต่อไปนี้:

ยูsชั่วโมงa=Lอีaโอa|ยังไม่มีข้อความอีsเสื้อโอยูsชั่วโมง(a×a)

ประเภทนี้หมายถึงองค์ประกอบของยูsชั่วโมงa is a tuple of as of length 2n for some n, since each time we go into the ยังไม่มีข้อความอีsเสื้อ constructor the type argument is paired with itself. So we can define the operator we want to take a fixed point of as:

F(R)=λX.{Lอีa(x)|xX}{ยังไม่มีข้อความอีsเสื้อ(โวลต์)|โวลต์R(X)}

ประเภทอุปนัยใน Coq เป็นหลัก GADT ที่ดัชนีของผู้ประกอบการประเภทไม่ จำกัด ประเภทอื่น ๆ (ในตัวอย่างเช่น Haskell) แต่ยังสามารถทำดัชนีโดยค่าของทฤษฎีประเภท ซึ่งช่วยให้คุณกำหนดประเภทสำหรับรายการที่มีการจัดทำดัชนีแบบยาวและอื่น ๆ


1
ขอขอบคุณ. แต่นั่นไม่ได้หมายถึงเพียงแค่ว่า "อุปนัยประเภท" ในความหมายเหมือนกันกับ "ประเภทพึ่งพา"?
ninjagecko

4
@Neel: ฉันไม่เคยเห็นประเภทเช่นbushเรียกว่า GADT ฉันเคยเห็นพวกเขาเรียกว่าประเภทซ้อนหรือไม่ธรรมดา
jbapple

3
ประเภทที่ซ้อนกันเป็นกรณีพิเศษของ GADT คุณสมบัติที่สำคัญของ GADT ก็คือมันเป็นนิยามแบบเรียกซ้ำที่สูงกว่า (การเปลี่ยนแปลงค่า rhs นั้นเป็นน้ำตาลเชิงประโยคสำหรับการเพิ่มความเสมอภาคแบบเป็นส่วนประกอบของคอนสตรัคเตอร์)
Neel Krishnaswami

4
@ninjagecko: "Inductive types" เป็นประเภทที่ให้ความหมายเป็นจุดคงที่ของตัวสร้าง ไม่ใช่ทุกประเภทที่สามารถอธิบายได้ด้วยวิธีนี้ (ฟังก์ชั่นไม่สามารถและไม่สามารถไม่มีประเภทเช่นสตรีม) ประเภทที่อ้างอิงขึ้นอยู่กับประเภทที่อนุญาตให้เงื่อนไขโปรแกรมเกิดขึ้นในพวกเขา (นั่นคือประเภทสามารถ "ขึ้นอยู่กับ" เงื่อนไข) เนื่องจาก 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 List aหากเราอนุญาตให้ Constructor ส่งคืนประเภทที่แตกต่างกันเรามี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 แต่มันลดภาระ syntax ของ GADT บ้างและมันสามารถนำไปสู่ข้อความแสดงข้อผิดพลาดที่ดีขึ้น


ขอขอบคุณ. "อุปนัยประเภทในภาษาการเขียนโปรแกรมที่มีชนิดขึ้นต่อกัน"ชนิดอุปนัยจะมีลักษณะอย่างไรในภาษาที่ไม่มีชนิดที่ขึ้นต่อกันและคุณสามารถมีชนิดพึ่งพาแบบไม่เหนี่ยวนำ (แต่คล้ายกับ GADT) ได้หรือไม่
ninjagecko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.