¿El sistema de tipos de Haskell es formalmente equivalente a Java? [cerrado]

66

Me doy cuenta de que algunas cosas son más fáciles / difíciles en un idioma que en el otro, pero solo me interesan las características relacionadas con el tipo que son posibles en uno e imposibles / irrelevantes en el otro. Para hacerlo más específico, ignoremos las extensiones de tipo Haskell ya que hay muchas personas que hacen todo tipo de cosas locas / geniales.

    
pregunta GlenPeterson 08.10.2012 - 17:50

4 respuestas

63

("Java", como se usa aquí, se define como estándar Java SE 7 ; "Haskell", como se usa aquí, se define como Haskell 2010 estándar .)

Cosas que tiene el sistema de tipos de Java pero que Haskell no tiene:

  • polimorfismo de subtipo nominal
  • información de tipo de tiempo de ejecución parcial

Cosas que tiene el sistema de tipos de Haskell pero que Java no:

  • polimorfismo ad-hoc acotado
    • da lugar a un polimorfismo de subtipo "basado en restricciones"
  • polimorfismo paramétrico de tipo superior
  • escritura principal

EDIT:

Ejemplos de cada uno de los puntos mencionados anteriormente:

Único a Java (en comparación con Haskell)

Polimorfismo del subtipo nominal

/* declare explicit subtypes (limited multiple inheritance is allowed) */
abstract class MyList extends AbstractList<String> implements RandomAccess {

    /* specify a type's additional initialization requirements */
    public MyList(elem1: String) {
        super() /* explicit call to a supertype's implementation */
        this.add(elem1) /* might be overridden in a subtype of this type */
    }

}

/* use a type as one of its supertypes (implicit upcasting) */
List<String> l = new ArrayList<>() /* some inference is available for generics */

Información de tipo de tiempo de ejecución parcial

/* find the outermost actual type of a value at runtime */
Class<?> c = l.getClass // will be 'java.util.ArrayList'

/* query the relationship between runtime and compile-time types */
Boolean b = l instanceOf MyList // will be 'false'

Único a Haskell (en comparación con Java)

Polimorfismo ad hoc acotado

-- declare a parametrized bound
class A t where
  -- provide a function via this bound
  tInt :: t Int
  -- require other bounds within the functions provided by this bound
  mtInt :: Monad m => m (t Int)
  mtInt = return tInt -- define bound-provided functions via other bound-provided functions

-- fullfill a bound
instance A Maybe where
  tInt = Just 5
  mtInt = return Nothing -- override defaults

-- require exactly the bounds you need (ideally)
tString :: (Functor t, A t) => t String
tString = fmap show tInt -- use bounds that are implied by a concrete type (e.g., "Show Int")

Polimorfismo de subtipo "basado en restricciones" (basado en polimorfismo ad-hoc acotado)

-- declare that a bound implies other bounds (introduce a subbound)
class (A t, Applicative t) => B t where -- bounds don't have to provide functions

-- use multiple bounds (intersection types in the context, union types in the full type)
mtString :: (Monad m, B t) => m (t String)
mtString = return mtInt -- use a bound that is implied by another bound (implicit upcasting)

optString :: Maybe String
optString = join mtString -- full types are contravariant in their contexts

Polimorfismo paramétrico de clase superior

-- parametrize types over type variables that are themselves parametrized
data OneOrTwoTs t x = OneVariableT (t x) | TwoFixedTs (t Int) (t String)

-- bounds can be higher-kinded, too
class MonadStrip s where
  -- use arbitrarily nested higher-kinded type variables
  strip :: (Monad m, MonadTrans t) => s t m a -> t m a -> m a

Escritura principal

Es difícil dar un ejemplo directo de este, pero significa que cada expresión tiene exactamente un tipo máximo general (llamado tipo principal ), que se considera el tipo canónico de esa expresión. En términos de polimorfismo de subtipo "basado en restricciones" (ver arriba), el tipo principal de una expresión es el subtipo único de cada tipo posible con el que se puede usar esa expresión. La presencia de la escritura principal en (no extendido) Haskell es lo que permite la inferencia de tipo completa (es decir, la inferencia de tipo exitosa para cada expresión, sin necesidad de ninguna anotación de tipo). Las extensiones que rompen la escritura principal (de las cuales hay muchas) también rompen la integridad de la inferencia de tipos.

    
respondido por el Ptharien's Flame 09.10.2012 - 06:37
32

El sistema de tipos de Java carece de un polimorfismo clasificado más alto; El sistema de tipos de Haskell lo tiene.

En otras palabras: en Java, los constructores de tipos pueden abstraerse sobre los tipos, pero no sobre los constructores de tipos, mientras que en Haskell, los constructores de tipos pueden abstraerse tanto de los constructores de tipos como de los tipos.

En inglés: en Java, un genérico no puede tomar otro tipo genérico y parametrizarlo,

public void <Foo> nonsense(Foo<Integer> i, Foo<String> j)

mientras que en Haskell esto es bastante fácil

higherKinded :: Functor f => f Int -> f String
higherKinded = fmap show
    
respondido por el Jörg W Mittag 08.10.2012 - 18:30
11

Para complementar las otras respuestas, el sistema de tipos de Haskell no tiene subtitulación , mientras que los lenguajes orientados a objetos escritos como Java lo hacen .

  

En teoría del lenguaje de programación , subtitulación (también subtipo polimorfismo o polimorfismo de inclusión ) es una forma de tipo polimorfismo en el que un < strong> subtty es un datatype que está relacionado con otro tipo de datos (el supertipo ) por alguna noción de capacidad de sustitución , lo que significa que los elementos del programa, normalmente subrutinas o funciones, escritos para operar en elementos del supertipo pueden También operan sobre elementos del subtipo. Si S es un subtipo de T, la relación de subtipo a menudo se escribe S & lt ;: T, para significar que cualquier término de tipo S se puede usar de manera segura en un contexto donde se espera un término de tipo T . La semántica precisa de los subtipos depende fundamentalmente de los detalles de lo que significa "uso seguro en un contexto donde" significa en un lenguaje de programación determinado. El sistema de tipo de un lenguaje de programación define esencialmente su propia relación de subtipo, que bien puede ser trivial.

     

Debido a la relación de subtipo, un término puede pertenecer a más de un tipo. Subtipo es por lo tanto una forma de polimorfismo tipo. En la programación orientada a objetos, el término 'polimorfismo' se usa comúnmente para referirse únicamente a este subtipo polimorfismo , mientras que las técnicas de polimorfismo paramétrico se considerarían programación genérica ...

    
respondido por el Petr Pudlák 08.10.2012 - 23:20
8

Una cosa que nadie mencionó hasta ahora es la inferencia de tipos: un compilador de Haskell generalmente puede inferir el tipo de expresiones, pero usted tiene que decirle al tipo de compilador de Java en detalle. Estrictamente, esta es una característica del compilador, pero el diseño del lenguaje y el sistema de tipos determina si la inferencia de tipos es factible. En particular, la inferencia de tipos interactúa mal con el polimorfismo de subtipo de Java y la sobrecarga ad hoc. En contraste, los diseñadores de Haskell se esfuerzan por no introducir características que impacten en la inferencia de tipos.

Otra cosa que las personas no parecen haber mencionado hasta ahora son los tipos de datos algebraicos. Es decir, la capacidad de construir tipos a partir de sumas ('o') y productos ('y') de otros tipos. Las clases de Java hacen productos (campo a y campo b, digamos) bien. Pero en realidad no hacen sumas (campo a O campo b, por ejemplo). Scala tiene que codificar esto como múltiples clases de casos, que no es exactamente lo mismo. Y si bien funciona para Scala, es un poco exagerado decir que Java lo tiene.

Haskell también puede construir tipos de funciones utilizando el constructor de funciones, - & gt ;. Si bien los métodos de Java tienen firmas de tipo, no se pueden combinar.

El sistema de tipos de

Java permite un tipo de modularidad que Haskell no tiene. Pasará un tiempo antes de que haya un OSGi para Haskell.

    
respondido por el GarethR 30.09.2013 - 20:43

Lea otras preguntas en las etiquetas