Quale frammento della teoria dei tipi dipendenti di Martin-Löf può essere espressa usando i tipi generici in Java?


8

Recentemente ho capito che una serie di problemi che ho avuto qualche anno fa nel tentativo di implementare varie teorie matematiche in Java sono dovuti al fatto che il sistema di digitazione in Java non è sufficientemente forte per modellare tutta la teoria del tipo dipendente da Martin-Löf .

Prima di Java 5 e farmaci generici, l'unico tipo teoria si potrebbe fare era attraverso le classi e interfacce, che vi danno i tipi arbitrari costruite fuori dai tipi di terreno int, double, chare così via utilizzando tipi di prodotto e di funzione. Puoi anche creare tipi ricorsivi come Lists, anche se non in modo uniforme.

Usando i generici, puoi fare un po 'di più. Ora puoi definire List<T>una funzione e quindi otteniamo tipi di ordini superiori.

TypeType

Questa non è la fine della storia, però. Usando un trucco generico, possiamo modellare alcuni tipi di prodotti dipendenti. Ad esempio, possiamo definire i tipi della forma usando la sintassi

T:Typef(T)
public interface f<T extends f<T>>
{
  // We can now refer to T as much as we like
  // inside the class.  T has type f<T>.
}

Ad esempio, possiamo modellare la struttura di base di base di un monoide (ma non le condizioni di associatività e unicità) usando un termine di tipo ( cioè, un insieme con un elemento di unità designato e un'operazione binaria su ). Usando i generici Java, possiamo modellare questo tipo:

T:TypeT×(TTT)
TT
public interface MonoidElement<T extends MonoidElement<T>>
{
  public T unit();

  public T mul(T op1, T op2);
}

Tuttavia, quando proviamo a modellare concetti più complicati, la teoria dei tipi si rompe.

Esiste una semplice descrizione del frammento di MLTT corrispondente ai tipi che possono essere creati nel sistema di tipizzazione Java?

Risposte:


12

Ci sono molte idee sbagliate qui. Per cominciare, MLTT non ha sottotipi, quindi Java non ne sarà semplicemente un frammento. Non richiede tipi dipendenti per creare uno dei tipi forniti. Un sistema di tipi dipendenti non ha bisogno di avere un "tipo" di tipi (un universo) in generale (MLTT ha universi però), né hai bisogno di tipi dipendenti per esprimere quei tipi. In un sistema come il calcolo lambda polimorfico / Sistema F , puoi dire . Java non ha alcun equivalente a Tipo. Un tipo dipendente senza un analogo come tipo polimorfico sarebbe qualcosa di simile ad esempio oT.T×(TTT)n:NatMatrix(n,n+1)b:Boolif b then Nat else Bool .

Ha più senso considerare Java un frammento di SystemF<: che non è affatto un sistema di tipo dipendente. Anche allora è un frammento piuttosto debole di esso. C'è una variante di System F chiamata System Fωche supporta funzioni di livello di tipo completo, essenzialmente lambda a livello di tipo (da non confondere con tipo-lambdas che mettono in relazione il valore e i livelli di tipo e il sistema F ha già). Né Java né Haskell possono farlo. Le uniche "funzioni" a livello di tipo che Haskell o Java (standard) possono eseguire sono composizioni di funzioni non interpretate. Non esiste alcun comportamento computazionale a livello di tipo. Java è ulteriormente limitato perché non ha (né ha bisogno di) un sistema gentile perché manca di tipi di tipo superiore. Cioè, non è possibile avere una "funzione" a livello di tipo con "tipo" (cioè tipo) per esempio. Questo è il motivo per cui non è possibile creare metodi che funzionano su monadi arbitrarie in Java. Tornando al solo Sistema F, il Sistema F ha tipi di rango arbitrari.(TypeType)Type quanto più ti piace - puoi usarlo liberamente. Né Java né Haskell (senza estensioni) supportano questo. Credo che entrambi possano catturare indirettamente alcuni tipi di rango superiore, ma nessuno dei due può esprimere il tipo di di Haskell che richiede estensioni ed è .runSTa.(s.ST s a)a

Quindi Java è più espressivo dei tipi di rango 1 catturati dal sistema di tipo Hindley-Milner ma molto meno espressivo di System . Non supporta alcuna forma di digitazione dipendente. Featherweight Java come introdotto in Featherweight Java: un calcolo core minimo per Java e GJ di Igarashi, Pierce e Wadler fornisce un calcolo semplificato e idealizzato specificamente orientato verso Java. C'è quasi certamente un documento che confronta / riduce direttamente Featherweight Java a System . Il risultato è che il sistema di tipi di Java non è nemmeno lontanamente vicino alla potenza di MLTT. In termini di cubo lambda , ignorando il sottotipo, Java sarebbe da qualche parte al limite traF<:F<:λ, il semplice calcolo lambda tipizzato e , System F. MLTT (o in particolare il calcolo delle costruzioni) è , l'angolo opposto di . Quindi la descrizione di Java in termini di MLTT richiederebbe prima di tutto di ignorare tutto ciò che ha reso MLTT diverso dal System F e quindi di ignorare quasi tutto ciò che ha reso System F diverso dal System F.λ2λPωλωω


Non sono sicuro di quali siano le idee sbagliate, ma grazie - questo ha praticamente risposto alla mia domanda.
John Gowers,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.