No, Haskell is wayyy easier to learn than Java. It has no NullPointerExceptions.
So let's compare the getLimit function in Haskell and in Java.
Haskell
getLimit :: [Int] -> Int
getLimit [] = 0
getLimit (x:xs) = x + getLimit xs
The problem with your implementation of getLimit was with the line getLimit [y:yz] = y + getLimit yz:
- The value
y:yz is of type [Int]. Hence [y:yz] is of type [[Int]] which is wrong.
- The compiler told you that. Learn to read error messages. What you want is just
(y:yz).
- The line
getLimit [x] = sum [x] is unnecessary.
Java
public int getLimit(int xs[]) {
int length = xs.length;
if (length == 0) return 0;
else return xs[0] + getLimit(Arrays.copyOfRange(xs, 1, length));
}
Of course in Java you would rather use for loops instead of recursion (which in my opinion is even worse because loops have no type and hence cannot be type checked by the compiler).
In contrast you can create looping constructs in Haskell which type check. For example the foldl function is defined as:
foldl :: (b -> a -> b) -> b -> [a] -> b
foldl _ a [] = a
foldl f a (x:xs) = foldl f (f a x) xs
This is equivalent to the following JavaScript code (sorry, I don't know how to use generics in Java):
function foldl(f, a, xs) {
for (var i = 0, l = xs.length; i < xs; i++)
a = f(a, xs[i]);
return a;
}
In short we have given a particular use case of a for loop a type.
Conclusion
Haskell is much better than Java. One of the best features of Haskell is generics. For example we can make getLimit a generic function which works on all types of numbers (not just Ints):
getLimit :: Num a => [a] -> a
getLimit [] = 0
getLimit (x:xs) = x + getLimit xs
The only thing we changed was the type signature of the function. Everything else remained the same. Try doing the same thing in Java.