3

The Hom functor Hom(-,-) is contravariant in the first argument and covariant in the second.

Can this fact somehow offer another explanation why Scala's Function1[-T1, +R] has the same property?

I have seen this claim made for example here, but at the point where the connection between the two concepts was supposed to be explained, there was so much hand waving it blew me away.

Bakuriu
  • 98,325
  • 22
  • 197
  • 231
rapt
  • 11,810
  • 35
  • 103
  • 145
  • I have removed [tag:haskell] since it seems completely unrelated to the question. If you care about haskell you have to specify explicitly what are you asking that's related to haskell. – Bakuriu May 29 '16 at 12:10

2 Answers2

7

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.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
  • 1
    I was just reading this great answer and thought: "Wow, great answer, he must know category theory well", and then I read the disclaimer.. LOL. Still, great answer. – Yuval Itzchakov May 29 '16 at 07:49
  • @n.m. You say there is a natural transformation from every covariant endofunctor on SET to every covariant endofunctor on POSET. How could that be? First, NT is defined on two functors that start from the same source category, and end in the same target category. This is not the case with SET and POSET. Second, NT preserves the internal structure of the categories. Again this is not the case. Many sets in SET are connected by morphisms that do not exist in POSET. – rapt May 30 '16 at 01:11
  • @rapt The first category s not SET, it's SCALA, the category of Scala types and functions). Similar but not the same.The second category is not POSET (my bad, wrong symbology fixed), it's **a** poset. (Each poset is a category). Call it SCALA-2. SCALA-2 is a subcategory of SCALA, the natural transformation arises naturally when you restrict an endofunctor on SCALA to SCALA-2. – n. m. could be an AI May 30 '16 at 04:07
  • @n.m. Could you please explain in more detail what you are trying to show in the last paragraph and what your motivation is ("Now it only remains to see that Function1...."). It's a little too telegraphic.. – rapt May 30 '16 at 05:40
  • @rapt hmm, as I said I'm no category theorist, I might be missing something. What is unclear/dubious in the last paragraph? – n. m. could be an AI May 30 '16 at 06:00
  • @n.m. You left a lot of details out from the last paragraph. It's not about more knowledge of CT, but being more precise in your definitions & arguments, & not leaving details to guessing, speculation, hand waving. It helps to understand you, & also catch incorrect arguments. Let's start with expanding that paragraph to explicitly explain for each of the functors Function1 and Hom(-,-), what is/are their source category/ies and target category. As always, to identify a category you have to specify its objects and its morphisms/arrows. Also, explain better how Function1 functor maps morphisms? – rapt May 30 '16 at 15:51
  • @rapt I didn't expect to write a CT treatise. I think what I have wrote is more or less self-evident. I have no idea how to write at the level of detail you require. I have tried and didn't like the result one bit. No experience in writing formal texts. Perhaps others can fill the gap. If you have specific questions I perhaps can answer interactively in a chat. – n. m. could be an AI May 30 '16 at 16:46
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/113345/discussion-between-rapt-and-n-m). – rapt May 30 '16 at 17:14
4

Probably not if you're careful about the setup. Function1 is very analogous to (the object part of) the Hom functor -- except that its target is not quite the same category. The target of the Function1 mapping is (a subcategory of) the scala category that has Scala types as objects and functions as arrows; while the target of the Hom functor is (a subcategory of) SET. Their images are probably isomorphic, but it's not clear that combining the two functors and the isomorphism preserves the structure in the way you need for variance to be preserved across the whole chain.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380