There are two categories of Scala types.
One is the usual types-and-functions category, where types are objects and arrows are functions.
The other one is the types-and-subtyping category, where types are objects and subtyping relationships are arrows. This category is a poset.
Covariance and contravariance in Scala is precisely covariance and contravariance of endofunctors in this latter category.
Now the second category happens to be a subcategory of the first one, due to projection arrows that map subtypes to supertypes. These arrows of the first category are exactly (all) the arrows of the second category. So every covariant endofunctor of the first category is naturally (that is, via a natural transformation) a covariant endofunctor of the second category.
Indeed, if a functor F
maps A
to A'
and B
to B'
and every arrow f: A -> B
to an arrow f': A' -> B'
, and if A
is a subtype of B
, then the projection arrow prj_A,B
is mapped to a projection arrow prj_A',B'
, and if one exists, then A'
is a subtype of B
'. Same thing about contravariant functors.
Now it only remains to see that Function1
is in a sense the Hom functor. Indeed if we see a Scala type as a set of its values, then Function1[A,B]
is a set of morphisms (Scala functions) from A
to B
. The arrow mapping is given by composition. And since it's covariant (contravariant) in the first category, it must be also covariant (contravariant) in the second category.
Edit:corrected subtype/supertupe confusion.
Disclaimer: I've never studied category theory. I may or may not know what I'm talking about.