I don't get this line -- "the Haskell compiler will complain because we still miss the definition of the type of the function."
That's not true. The compiler will give the function the most general type it can infer, which in this case is
holds :: Eq a => UnionFindElement a -> a -> Bool
without you needing to specify it in the file.
The point of the article is sound - using the interpreter to ask for types is a great way to work (and often leads to surprising realizations which can lead you to generalize and abstract your code), but the reasoning is spurious. Most of the time, you don't need to supply types in Haskell, as the compiler is perfectly capable of figuring them out for itself.
Most of the time, you don't need to supply types in Haskell, as the compiler is perfectly capable of figuring them out for itself.
I love type inference, but I feel like using it in this way doesn't realize its full potential. My functional background primarily stems from SML (and some Clojure), but the logic I'll use should apply here as well. It's true that the compiler is able to infer the most general type itself, but if you rely on it for this you're ignoring an invaluable tool for predicting the correctness of your code.
There are many times where I've used type inference to show me there's an issue with my code before I even run a single unit-test. I always specify the types of my arguments as well as the return type when writing a function, even though it's not technically required at this point. If I've fully reasoned through what it needs to do then this shouldn't be too difficult. Once I've finished I'll make sure it type-checks. If it does then I'll know the logic throughout my function matches the inputs and outputs I've specified.
That gives you a powerful low-pass filter for knowing whether or not your code is more likely to be correct. If you specify the types when you declare the function and they don't match then your code won't type-check, which results in an exception. If you don't, then depending on the type of error your function might still type-check and compile, but with the wrong type. Then you have no choice but to catch the error with unit tests or, even worse, debugging. The interpreter will certainly give you the type for the code that you've entered, but assuming that it's giving you the type for the code you actually need leaves a powerful tool on the table.
Obviously this doesn't cover every class of error you could have in your code of course, but it in my experience it can be very helpful.
Specifying types is not a bad thing, I also do it myself of course. However, the more general the type signatures are, the more that can be reasoned about what a function can do. i.e. there is a lot more that a function of type Int -> Int -> Int can do than say (Num a) => a -> a -> a. So I try to always use the most generic version of the type I can.
If you're using emacs with a recent haskell-mode and you have the file loaded into a ghci session, then C-c C-t will get you the same information. (C-u C-c C-t will ask ghci and insert the type signature in the line above)
More specifically, you remove your type annotations for the target functions/values entirely, and then ask GHCi what it thinks by loading the module into it.
You should then examine the result and make sure it is correct. In this case, you wrote the type signature incorrectly on an otherwise-correct function, but you will also frequently find that what you wrote is syntactically valid but has a type you did not intend at all, because it is actually wrong. For instance, it's easy to end up missing a parameter passing somewhere and ending up with an unexpected function showing up in the inferred signature.
You can also find that the GHCi-inferred type signature is correct, but not what you particularly wanted. Sometimes you may want to deliberately constrain it to something tighter than it will infer. And the other major case I've seen is that you may want to write the type signature with synonyms you've created; if you fix the type signature with those, GHCi will use them in the future if you ask for the type.