Expanding on this a bit...
You could think of there being a universe U of programming fundamentals. Each language uses a subset of U as the language's fundamentals (no language uses all of it), and each language uses a different subset.
Some languages have subsets that overlap, but that isn't always obvious, because they clothe the same thing in different syntax and, sometimes, different semantics. Even when the semantics are the same, they talk about the semantics using different terms.
So the problems with transferring knowledge of the fundamentals from one language to another are that they aren't the same fundamentals (different subsets of U), and that they are expressed in different terms and in different syntax. That can make it hard to recognize that the parts that are in common actually are the same. And then there's the new parts.
Now here's a class in C#. One student comes in knowing Haskell; one comes in knowing Python; and one comes in knowing C. The "fundamentals to transfer" differ from student to student. It's asking a lot for the teacher to be able to help each student recognize what part of their background transfers, what part of C# it transfers to, and what the deeper fundamentals are that are expressed in both languages. An exceptional teacher could certainly do so, but as the adjective implies, such teachers are the exception.
But it's not really fair to blame the student, either. It's asking a lot of a 19-year-old to understand deeply enough to make those connections.
My own guess is that this happens best after working as a professional for several years, and in more than one language. Then it's somewhat easier to see what's going on "under the hood" of the languages.