("Java", như được sử dụng ở đây, được định nghĩa là Java SE 7 tiêu chuẩn ; "Haskell", như được sử dụng ở đây, được định nghĩa là Haskell tiêu chuẩn 2010. )
Những thứ mà hệ thống kiểu Java có nhưng Haskell thì không:
- đa hình danh nghĩa
- thông tin loại thời gian chạy một phần
Những thứ mà hệ thống loại của Haskell có nhưng Java thì không:
- đa hình ad-hoc giới hạn
- làm phát sinh tính đa hình phụ "dựa trên ràng buộc"
- đa hình tham số loại cao hơn
- gõ chính
BIÊN TẬP:
Ví dụ về mỗi điểm được liệt kê ở trên:
Duy nhất với Java (so với Haskell)
Đa hình danh nghĩa
/* 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 */
Thông tin loại thời gian chạy một phần
/* 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'
Duy nhất với Haskell (so với Java)
Đa hình ad-hoc
-- 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")
Dạng đa hình phụ "dựa trên ràng buộc" (dựa trên đa hình ad-hoc bị ràng buộc)
-- 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
Đa hình tham số loại cao hơn
-- 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
Gõ chính
Đây là một ví dụ khó đưa ra một ví dụ trực tiếp, nhưng nó có nghĩa là mọi biểu thức đều có chính xác một loại tổng quát tối đa (được gọi là loại chính của nó ), được coi là loại chính tắc của biểu thức đó. Về mặt đa hình của kiểu con "dựa trên ràng buộc" (xem ở trên), kiểu chính của biểu thức là kiểu con duy nhất của mọi loại có thể mà biểu thức đó có thể được sử dụng như. Sự hiện diện của việc gõ chính trong Haskell (không được giám sát) là những gì cho phép suy luận kiểu hoàn chỉnh (nghĩa là suy luận kiểu thành công cho mọi biểu thức, mà không cần bất kỳ chú thích loại nào). Các phần mở rộng phá vỡ kiểu gõ chính (trong đó có nhiều phần) cũng phá vỡ tính hoàn chỉnh của suy luận kiểu.