This is more a comment than an actual answer, but I require more space.
While the type systems of Java and Haskell are quite apart, some similarities can be found in certain features. Here are a few examples: just keep in mind that there is no perfect correspondence between the related constructs shown below.
Polymorphic functions (as in FP, not OOP polymorphism):
fst :: forall a b. (a, b) -> a
fst (x,y) = x
<A,B> A fst(A a, B b) {
return a;
}
Note that polymorphic non-function values can not be translated as easily. Even in Haskell, values such as 3 :: Num a => a
are functions in disguise. Further, [] :: [a]
and Nothing :: Maybe a
are also treated as functions, taking a "type" parameter in some stages of compilation -- albeit, IIRC at runtime these parameter disappear.
Type arguments:
data T a = T a Int a
class T<A> {
A x;
int n;
A y;
T(A x, int n, A y) {
this.x = x; this.n = n; this.y = y;
}
}
Algebraic data types (e.g. data
with many constructors): these are not directly available in Java. Some other JVM languages, like Scala, have ADT supported directly in the language, as well as pattern patching and non-exhaustiveness warnings. In Java, you can use the so-called Visitor pattern to simulate ADT value elimination, which is a basic form of pattern matching.