Може хтось зможе пояснити різницю між:
- Алгебраїчні типи даних (з якими я досить добре знайомий)
- Узагальнені типи алгебраїчних даних (що робить їх узагальненими?)
- Індуктивні типи (наприклад, Coq)
(Особливо спонукальні типи.) Дякую.
Може хтось зможе пояснити різницю між:
(Особливо спонукальні типи.) Дякую.
Відповіді:
Алгебраїчні типи даних дозволяють визначати типи рекурсивно. Конкретно, припустимо, у нас є тип даних
Це означає, що - найменший набір, що генерується операторами N i l і C o n s . Ми можемо це формалізувати, визначивши оператор F ( X )
а потім визначення як
Узагальнено ADT є те , що ми отримуємо , коли визначити тип оператора рекурсивно. Наприклад, ми можемо визначити такий конструктор типу:
Цей тип означає, що елемент є кортежем через з довжиною 2 п для деякого п , таккожен разми в N е з т конструктора типу аргументпарі з самим собою. Таким чином, ми можемо визначити оператора, якого ми хочемо прийняти за фіксовану точку як:
Індуктивний тип у Coq, по суті, є GADT, де індекси оператора типу не обмежуються іншими типами (як, наприклад, у Haskell), але можуть також індексуватися значеннями теорії типів. Це дозволяє надати типи для списків, що індексуються за довжиною тощо.
bush
GADT. Я бачив, як вони називаються вкладеними або нерегулярними типами.
bush a
? У цьому прикладі це Nest Leaf(a) Leaf(a) Leaf(a) Leaf(a)
чи Nest ((Nest Leaf(a) Leaf(a)) (Nest Leaf(a) Leaf(a)))
як один із прикладів безлічі?
Розглянемо алгебраїчні типи даних, такі як:
data List a = Nil | Cons a (List a)
Типи повернення кожного конструктора в типі даних всі однакові: Nil
і Cons
обидва повертаються 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, і це може призвести до кращих повідомлень про помилки.