¿Qué fragmento de la teoría de tipos dependiente de Martin-Löf se puede expresar utilizando tipos genéricos en Java?


8

Recientemente me di cuenta de que una serie de problemas que tuve hace unos años al tratar de implementar varias teorías matemáticas en Java se redujeron al hecho de que el sistema de escritura en Java no es lo suficientemente fuerte como para modelar toda la teoría de tipos dependiente de Martin-Löf .

Antes de Java 5 y los genéricos, el único tipo teoría se podía hacer era a través de clases e interfaces, que le dan tipos arbitrarios construidas a partir de los tipos de suelo int, double, chary así sucesivamente utilizando tipos y funcionamiento del producto. También puede crear tipos recursivos como Lists, aunque no de manera uniforme.

Usando genéricos, puede hacer un poco más. Ahora puede definir List<T>como una función y así obtenemos tipos de orden superior.

TypeType

Sin embargo, este no es el final de la historia. Usando un truco genérico, podemos modelar algunos tipos de productos dependientes. Por ejemplo, podemos definir tipos de la forma usando la sintaxis

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>.
}

Como ejemplo, podemos modelar la estructura básica subyacente de un monoide (pero no las condiciones de asociatividad y unitalidad) usando un término de tipo ( es decir, un conjunto con un elemento de unidad designado y una operación binaria en ). Usando genéricos de Java, podemos modelar este tipo:

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

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

Sin embargo, cuando intentamos modelar conceptos más complicados, la teoría de tipos se rompe.

¿Existe una descripción simple del fragmento de MLTT correspondiente a los tipos que se pueden construir en el sistema de escritura Java?

Respuestas:


12

Hay muchas ideas falsas aquí. Para comenzar, MLTT no tiene subtipos, por lo que Java no será simplemente un fragmento de él. No requiere tipos dependientes para hacer ninguno de los tipos que proporcionó. Un sistema de tipos dependientes no necesita tener un "tipo" de tipos (un universo) en general (MLTT sí tiene universos), ni necesita tipos dependientes para expresar esos tipos. En un sistema como el cálculo lambda polimórfico / Sistema F , puede decir . Java no tiene ningún equivalente a Tipo. Un tipo dependiente sin un análogo como tipo polimórfico sería algo como, por ejemplo, oT.T×(TTT)n:NatMatrix(n,n+1)si:sioolyoF si thminorte norteunat milsmi siool .

Tiene más sentido considerar Java como un fragmento de SystemF<: que no es un sistema de tipo dependiente en absoluto. Incluso entonces es un fragmento bastante débil del mismo. Hay una variante del Sistema F llamada Sistema Fωque admite funciones de nivel de tipo completo, esencialmente lambda en el nivel de tipo (no debe confundirse con type-lambdas que relacionan el valor y los niveles de tipo y el Sistema F ya lo tiene). Ni Java ni Haskell pueden hacer esto. Las únicas "funciones" de nivel de tipo que pueden hacer Haskell o Java (estándar) son composiciones de funciones no interpretadas. No hay comportamiento computacional a nivel de tipo. Java está más restringido porque no tiene (ni necesita) un sistema amable porque carece de tipos de tipo superior. Es decir, no puede tener una "función" de nivel de tipo con "tipo" (es decir, tipo) por ejemplo. Es por eso que no puede crear métodos que operen sobre mónadas arbitrarias en Java. Volviendo solo al Sistema F, el Sistema F tiene tipos de rango arbitrarios.(TypagsmiTypagsmi)Typagsmi lo que quieras, puedes usarlo libremente. Ni Java ni Haskell (sin extensiones) lo admiten. Creo que ambos pueden capturar indirectamente algunos tipos de rango superior, pero ninguno puede expresar el tipo de que requiere extensiones y es .rtunorteSTuna.(s.ST s una)una

Entonces, Java es más expresivo que los tipos de rango 1 capturados por el sistema de tipos Hindley-Milner, pero mucho menos expresivo que System . No admite ninguna forma de escritura dependiente. Featherweight Java, tal como se introdujo en Featherweight Java: A Minimal Core Calculus for Java and GJ por Igarashi, Pierce y Wadler, proporciona un cálculo simplificado e idealizado específicamente dirigido a Java. Es casi seguro que hay un documento que compara / reduce directamente Featherweight Java a System . El resultado es que el sistema de tipos de Java no está ni remotamente cerca del poder de MLTT. En términos del cubo lambda , ignorando el subtipo, Java estaría en algún lugar entreF<:F<:λ, el cálculo lambda de tipo simple y , Sistema F. MLTT (o específicamente el cálculo de construcciones) es , la esquina opuesta a . Por lo tanto, describir Java en términos de MLTT primero requeriría ignorar todo lo que hizo que MLTT fuera diferente del Sistema F y luego ignorar casi todo lo que hizo que el Sistema F diferente del Sistema F.λ2λPAGSωλωω


No estoy seguro de cuáles son los conceptos erróneos, pero gracias, esto ha respondido a mi pregunta.
John Gowers
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.