Me gustaría saber si un tipo universalmente cuantificado : T a = ∀ X : { a ∈ X , f : X → { T , F } } es un subtipo o caso especial, de un caso cuantificado existencialmente escriba T e con la misma firma: T e = ∃ X : { a ∈ X , f : X → { T , F } }
Yo diría "sí": si algo es cierto "para todas las X" ( ), entonces también debe ser cierto "para algunas X" ( ∃ X ). Es decir, una declaración con ' ∀ ' es simplemente una versión más restringida de la misma declaración con ' ∃ ': ∀ X , P ( X ) ?
¿Me equivoco en alguna parte?
Antecedentes: ¿por qué pregunto esto?
Estoy estudiando tipos existenciales para entender por qué y cómo los "tipos abstractos [de datos] tienen tipo existencial" . No puedo entender bien este concepto solo de la teoría; También necesito ejemplos concretos.
Desafortunadamente, es difícil encontrar buenos ejemplos de código porque la mayoría de los lenguajes de programación solo tienen soporte limitado para tipos existenciales. (Por ejemplo, los comodines de Haskell
forall
o Java?
). Por otro lado, los tipos cuantificados universalmente son compatibles con muchos idiomas recientes a través de "genéricos".Lo que es peor, los genéricos también se mezclan fácilmente con los tipos existenciales , lo que hace que sea aún más difícil distinguir los tipos existenciales de los universales. Tengo curiosidad por qué esta confusión ocurre tan fácilmente. Una respuesta a esta pregunta podría explicarlo: si los tipos universales son solo un caso especial de tipos existenciales, entonces no es de extrañar que los tipos genéricos, por ejemplo, Java
List<T>
, puedan interpretarse de cualquier manera.
forall x. P(x)
así exists x. P(x)
. Si los sistemas de tipos tienen esto en cuenta al verificar los tipos ... No tengo idea. +1 para una pregunta interesante.