Hi Anatoliy,
In the case of
fOrd[A](createRoot)
You have specified `A` explicitly, so that is now fixed, and the expected return type of the parameter is therefore `A`. So far, so good.
What that means is that you can provide any parameter whose type is a subtype of `A`. As far as the compiler is concerned, `Nothing` is as good a type as any, so it chooses `Nothing` in the absence of any other constraints on the type. In theory, it could equally choose `A` or an arbitrary subtype of `A`, but type inference is solving a system of constraints, and the parameter `T` in `createRoot` is underconstrained.
So, why does this case do what we want?
fMon[A](createMonad)
The analysis is the same up to the application of `createMonad`. The expected type of the parameter is `Monad[A]`, which means that you can provide any parameter whose type is a subtype of `Monad[A]`. But because `T` is *invariant* in `Monad[T]`, that `T` must be exactly the same `A` for *all* subtypes of `Monad[A]`.
Put another way, `Monad[T]` can vary without `T` varying, but `T` cannot vary without `T` varying.
Hope that helps.
Cheers,
Jon