I realize some things are easier/harder in one language than the other, but I'm only interested in type-related features that are possible in one and impossible/irrelevant in the other. To make it more specific, let's ignore Haskell type extensions since there's so many out there that do all kinds of crazy/cool stuff.
- Anybody can ask a question
- Anybody can answer
- The best answers are voted up and rise to the top
There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.If this question can be reworded to fit the rules in the help center, please edit the question.
Things that Java's type system has but that Haskell's doesn't:
Things that Haskell's type system has but that Java's doesn't:
Examples of each of the points listed above:
Unique to Java (as compared to Haskell)
Nominal subtype polymorphism
Partial runtime type information
Unique to Haskell (as compared to Java)
Bounded ad-hoc polymorphism
"Constraint-based" subtype polymorphism (based on bounded ad-hoc polymorphism)
Higher-kinded parametric polymorphism
This one is difficult to give a direct example of, but it means that every expression has exactly one maximally general type (called its principal type), which is considered the canonical type of that expression. In terms of "constraint-based" subtype polymorphism (see above), the principal type of an expression is the unique subtype of every possible type that that expression can be used as. The presence of principal typing in (unextended) Haskell is what allows complete type inference (that is, successful type inference for every expression, without any type annotations needed). Extensions that break principal typing (of which there are many) also break the completeness of type inference.
Java's type system lacks higher kinded polymorphism; Haskell's type system has it.
In other words: in Java, type constructors can abstract over types, but not over type constructors, whereas in Haskell, type constructors can abstract over type constructors as well as types.
In English: in Java a generic can't take in another generic type and parameterize it,
while in Haskell this is quite easy
To complement the other answers, Haskell's type system doesn't have subtyping, while typed object oriented languages as Java do.
One thing nobody's mentioned so far is type inference: a Haskell compiler can usually infer the type of expressions but you have to tell the Java compiler your types in detail. Strictly, this is a feature of the compiler but the design of the language and type system determines whether type inference is feasible. In particular, type inference interacts badly with Java's subtype polymorphism and ad hoc overloading. In contrast, the designers of Haskell try hard not to introduce features that impact type inference.
Another thing people don't seem to have mentioned so far is algebraic data types. That is, the ability to construct types from sums ('or') and products ('and') of other types. Java classes do products (field a and field b, say) fine. But they don't really do sums (field a OR field b, say). Scala has to encode this as multiple case classes, which isn't quite the same. And while it works for Scala it's a bit of a stretch to say Java has it.
Haskell can also construct function types using the function constructor, ->. While Java's methods do have type signatures, you can't combine them.
Java's type system does enable a type of modularity that Haskell hasn't got. It will be a while before there's an OSGi for Haskell.
Some minor differences:
protected by gnat May 31 '15 at 8:44
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?