("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.