Я позволю себе переименовать типы данных.Первый, индексированный по Set
, будет называться ListI
, а второй ListP
имеет Set
в качестве параметра:
data ListI : Set → Set₁ where
[] : {A : Set} → ListI A
_∷_ : {A : Set} → A → ListI A → ListI A
data ListP (A : Set) : Set where
[] : ListP A
_∷_ : A → ListP A → ListP A
В типах данных параметры идут перед двоеточием,и аргументы после двоеточия называются указами.Конструкторы могут быть использованы таким же образом, вы можете применить неявный набор:
nilI : {A : Set} → ListI A
nilI {A} = [] {A}
nilP : {A : Set} → ListP A
nilP {A} = [] {A}
Разница возникает при сопоставлении с образцом.Для индексированной версии у нас есть:
null : {A : Set} → ListI A → Bool
null ([] {A}) = true
null (_∷_ {A} _ _) = false
Этого нельзя сделать для ListP
:
-- does not work
null′ : {A : Set} → ListP A → Bool
null′ ([] {A}) = true
null′ (_∷_ {A} _ _) = false
Сообщение об ошибке:
The constructor [] expects 0 arguments, but has been given 1
when checking that the pattern [] {A} has type ListP A
ListP
также может быть определен с помощью фиктивного модуля, как ListD
:
module Dummy (A : Set) where
data ListD : Set where
[] : ListD
_∷_ : A → ListD → ListD
open Dummy public
Возможно, немного удивительно, ListD
равен ListP
.Мы не можем сопоставить шаблон с аргументом Dummy
:
-- does not work
null″ : {A : Set} → ListD A → Bool
null″ ([] {A}) = true
null″ (_∷_ {A} _ _) = false
Это выдает то же сообщение об ошибке, что и для ListP
.
ListP
- пример параметризованного типа данных, что проще, чем ListI
, который является индуктивным семейством: он «зависит» от признаков, хотя в этом примере это тривиальным образом.
Параметризованные типы данных определены в в вики и здесь - небольшое введение.
Индуктивные семейства на самом деле не определены, а детально проработаны в вики с каноническим примером чего-то, что кажетсянужны индуктивные семейства:
data Term (Γ : Ctx) : Type → Set where
var : Var Γ τ → Term Γ τ
app : Term Γ (σ → τ) → Term Γ σ → Term Γ τ
lam : Term (Γ , σ) τ → Term Γ (σ → τ)
Вне зависимости от индекса типа упрощенная версия этого не может быть записана с помощью Dummy
-модуля из-за конструктора lam
.
Другойхороший пример - Индуктивные семьи Питера Дайбджера с 1997 года.
Счастливого кодирования Agda!