(«Java», как здесь используется, определяется как стандарт Java SE 7 ; «Haskell», как здесь используется, определяется как стандарт Haskell 2010 ).
Вещи, которые есть в системе типов Java, но нет в Haskell:
- номинальный полиморфизм подтипа
- частичная информация о типе среды выполнения
Вещи, которые есть в системе типов Haskell, а в Java - нет:
- ограниченный специальный полиморфизм
- порождает "основанный на ограничениях" полиморфизм подтипа
- параметрический полиморфизм высшего рода
- основной тип
РЕДАКТИРОВАТЬ:
Примеры каждого из пунктов, перечисленных выше:
Уникально для Java (по сравнению с Haskell)
Номинальный подтип полиморфизма
/* 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 */
Частичная информация о типе среды выполнения
/* 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'
Уникально для Haskell (по сравнению с Java)
Ограниченный специальный полиморфизм
-- 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")
«Основанный на ограничениях» полиморфизм подтипа (основанный на ограниченном специальном полиморфизме)
-- 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
Высоко-родственный параметрический полиморфизм
-- 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
Основной тип
Этот пример трудно привести к прямому примеру, но это означает, что каждое выражение имеет ровно один максимально общий тип (называемый его основным типом ), который считается каноническим типом этого выражения. В терминах «основанного на ограничениях» полиморфизма подтипа (см. Выше) основным типом выражения является уникальный подтип каждого возможного типа, в котором это выражение может использоваться. Наличие основной типизации в (нерасширенном) Haskell - это то, что допускает полный вывод типов (то есть успешный вывод типов для каждого выражения, без необходимости каких-либо аннотаций типов). Расширения, которые нарушают основную типизацию (которых много) также нарушают полноту вывода типов.