I asked this question a while ago - the answers were really helpful, and as I read them and the questions that were linked - I also saw this, and the first answer I think really addresses what I thought was the essence of the more powerful type system.
I was trying to really understand the pseudo-implementation of the functor that the author gives in his example - and I wondered if anyone can give me a slightly simpler explanation of this part of his answer.
Directly quoted from the answer - it's these bits that I don't quite get.
for this block of code.
interface Functor<A> {
Functor<B> map(Function<A, B> f);
}
- The type system doesn't allow us to express the invariant that the map method always returns the same Functor subclass as the receiver.
- Therefore, there's no statically type-safe manner to invoke a non-Functor method on the result of map.
Is a simple way of looking at this that in a concrete implementation of Functor
, you can declare what you want to use as A
, but not what you want to use as B, or even the B
is the same on both sides of the map function?
More generall, my slightly simplistic interpretation of this is that single-kinded types really mean that it limits how far you can "reach" or "specify" the contract you are trying to specify with your types. With higher kinded types, you get much more flexibility on how you specify your types, i.e you can constrain and bind your functions more specifically that you can with simple java generics.
... or I really it could be that I just don't understand what a Type Constructor is or why it's useful!