("Java", seperti yang digunakan di sini, didefinisikan sebagai standar Java SE 7 ; "Haskell", seperti yang digunakan di sini, didefinisikan sebagai standar Haskell 2010. )
Hal-hal yang dimiliki sistem tipe Java tetapi Haskell tidak:
- polimorfisme subtipe nominal
- informasi jenis runtime parsial
Hal-hal yang dimiliki sistem tipe Haskell tetapi Java tidak:
- polimorfisme ad-hoc terbatas
- memunculkan polimorfisme subtipe "berbasis kendala"
- polimorfisme parametrik yang lebih tinggi
- pengetikan utama
SUNTING:
Contoh masing-masing poin yang tercantum di atas:
Unik untuk Jawa (dibandingkan dengan Haskell)
Polimorfisme subtipe 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 */
Informasi jenis runtime parsial
/* 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'
Unik untuk Haskell (dibandingkan dengan Jawa)
Polimorfisme ad-hoc terbatas
-- 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")
Polimorfisme subtipe "berbasis kendala" (berdasarkan polimorfisme ad-hoc terbatas)
-- 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
Polimorfisme parametrik yang lebih baik
-- 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
Pengetikan kepala sekolah
Yang ini sulit untuk memberikan contoh langsung, tetapi itu berarti bahwa setiap ungkapan memiliki tepat satu jenis umum secara maksimal (disebut jenis utamanya ), yang dianggap sebagai jenis kanonik dari ungkapan itu. Dalam hal polimorfisme subtipe "berbasis kendala" (lihat di atas), tipe utama dari sebuah ekspresi adalah subtipe unik dari setiap jenis yang mungkin digunakan untuk ekspresi tersebut. Kehadiran pengetikan utama dalam (tidak diperluas) Haskell adalah yang memungkinkan inferensi tipe lengkap (yaitu, inferensi tipe yang berhasil untuk setiap ekspresi, tanpa anotasi jenis apa pun yang diperlukan). Ekstensi yang melanggar pengetikan utama (yang jumlahnya banyak) juga merusak kelengkapan inferensi tipe.