("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 - це те, що дозволяє зробити повний висновок типу (тобто, вдалий умовивід для кожного виразу, без необхідних анотацій типу). Розширення, які порушують основне введення тексту (яких існує багато), також порушують повноту виводу типу.