Prima una spiegazione terminologica: posizioni negative e positive provengono dalla logica. Sono circa un'asimmetria nella connettivi logici: in della A comporta in modo diverso da B . Una cosa simile accade nella teoria delle categorie, dove diciamo rispettivamente contravarianza e covariante anziché negativa e positiva. In fisica parlano di quantità che si comportano "in modo covariante" e "anche in modo contraddittorio. Quindi questo è un fenomeno molto generale. Un programmatore potrebbe pensare a loro come" input "e" output ".A ⇒ BUNB
Ora su tipi di dati induttivi.
TTT
In algebra è consuetudine che un'operazione prenda un numero finito di argomenti, e nella maggior parte dei casi prende zero (costante), uno (unario) o due (binari) argomenti. È conveniente generalizzare questo per i costruttori di tipi di dati. Supponiamo che c
sia un costruttore per un tipo di dati T
:
- se
c
è una costante possiamo pensarla come una funzione unit -> T
, o equivalentemente (empty -> T) -> T
,
- se
c
è unario possiamo considerarlo come una funzione T -> T
, o equivalentemente (unit -> T) -> T
,
- se
c
è binario possiamo considerarlo come una funzione T -> T -> T
, o in modo equivalente T * T -> T
o equivalente (bool -> T) -> T
,
- se volessimo un costruttore
c
che accetta sette argomenti, potremmo vederlo come una funzione in (seven -> T) -> T
cui seven
esiste un tipo precedentemente definito con sette elementi.
- possiamo anche avere un costruttore
c
che accetta numerosamente infiniti argomenti, che sarebbe una funzione (nat -> T) -> T
.
Questi esempi mostrano che dovrebbe essere la forma generale di un costruttore
c : (A -> T) -> T
dove chiamiamo l'arity di e pensiamo come un costruttore che prende argomenti -vari di tipo per produrre un elemento di .A
c
c
A
T
T
Ecco qualcosa di molto importante: le arità devono essere definite prima di definire T
, altrimenti non possiamo dire cosa dovrebbero fare i costruttori. Se qualcuno prova ad avere un costruttore
broken: (T -> T) -> T
quindi la domanda "quanti argomenti ci broken
vogliono?" non ha una buona risposta. Potresti provare a rispondere con "richiede T
-molti argomenti", ma ciò non funzionerà, perché T
non è ancora definito. Potremmo provare a uscire dal caos usando una teoria a virgola fissa per trovare un tipo T
e una funzione iniettiva (T -> T) -> T
, e ci riusciremmo, ma infrangeremmo anche il principio dell'induzione T
. Quindi, è solo una cattiva idea provare una cosa del genere.
λvλ ⋅ vc
B
c : B * (A -> T) -> T
In effetti, molti costruttori possono essere riscritti in questo modo, ma non tutti, abbiamo bisogno di un ulteriore passo, vale a dire che dovremmo consentire A
di dipendere da B
:
c : (∑ (x : B), A x -> T) -> T
Questa è la forma finale di un costruttore per un tipo induttivo. È anche esattamente ciò che sono i tipi W. La forma è così generale che abbiamo sempre e solo bisogno di un solo costruttore c
! Anzi, se ne abbiamo due
d' : (∑ (x : B'), A' x -> T) -> T
d'' : (∑ (x : B''), A'' x -> T) -> T
allora possiamo combinarli in uno
d : (∑ (x : B), A x -> T) -> T
dove
B := B' + B''
A(inl x) := A' x
A(inr x) := A'' x
A proposito, se curry la forma generale vediamo che è equivalente a
c : ∏ (x : B), ((A x -> T) -> T)
che è più vicino a ciò che le persone effettivamente scrivono negli assistenti di prova. Gli assistenti di prova ci permettono di scrivere i costruttori in modo conveniente, ma quelli sono equivalenti al modulo generale sopra (esercizio!).
A
ed eventualmente esplodere lo stack (in linguaggi basati su stack).