Hindley-Milner has problems with inferring types in the presence of polymorphic recursion, and a user provided type annotation is usually necessary. Polymorphic recursion does allow some cool things such as arbitrarily nested lists. This is a feature that users from a dynamically typed language might miss.
OCaml and Haskell support it by requiring type annotations.
In general, polymorphic recursion is occasionally useful for some specific data structures (see Okasaki's purely functional datastructures for some examples) and when playing with GADTs.
Additionally, GHC will try to monomorphise bounded functions if it can, because it's simply much faster without the extra layer of indirection.
I could be equating a few things which aren't equal, but I'd love to hear your take (or anyone elses)
Ex.
def fact(n: Int) = if (n == 0) 1 else n * fact(n - 1)
will fail to compile and tell you that you need to provide a return type.
Strictly speaking Hindley-Milner never requires type annotations. It can infer the type of any well-formed expression. You must be thinking of some extension of HM (of which there are many).
Here is an example of the type error (I used the datatype from the Wikipedia article on polymorphic recursion): https://repl.it/@CalebHelbling/PolymorphicRecursionError
What do you mean? You can implement arbitrarily nested lists (rose trees) in Haskell.
data Tree1 a = Leaf1 a | Node1 [Tree1 a]
flatten :: Tree1 -> [a]
But this type needs it:
data Tree2 a = Leaf2 a | Node2 (Tree2 [a])
flatten2 :: Tree2 -> [a]
Tree1 can vary in depth between nodes, while Tree2 is either a, [a], [[a]], [[[a]]] etc.
"Cool" as it might be, please don't inflict it on others.
datatype 'a tree = T of 'a * 'a tree list
Do you?