How to create functors?

Paul Rubin http
Sun Aug 23 07:27:57 CEST 2009

```Steven D'Aprano <steven at REMOVE.THIS.cybersource.com.au> writes:
> According to Wikipedia, functor can be used as a synonym for "function
> object": ... http://en.wikipedia.org/wiki/Function_object

Hmm, I hadn't seen that usage before.  I guess there's no law against
it, but it seems a bit bogus to me.

> I find the Haskell page entirely opaque and unintelligible... The

I thought it was the other way around, but I've been banging my head
against Haskell on and off for the past year or so, so it could be
some familiarity with Haskell and its type system.

Here's another attempt of my own, from the mathematical perspective:
"categories" generalize the concept of structured collections of
objects.  For example, groups, rings, and sets are each a type of
structured collection, so there is a category of groups (called "Grp"
since for some reason categorists like to use capitalized, abbreviated
names), a category of rings ("Rng"), and a category of sets ("Set").
Each category has a collection of objects and a collection of "arrows"
(sometimes called morphisms) which are associative relations between
objects in the category.  So in the category of sets, the objects are
sets and the arrows are functions mapping one set to another.  In the
category of groups, the objects are groups and the arrows are the
homeomorphisms between groups.

Functors are mappings from one category to another, that map both the
objects and the arrows.  That is they are arrows on the categories of
categories.

The concepts of categories and functors came from the loftier reaches
of algebraic geometry (further in math than I ever got) in the 1950's
or so.  These days they turn out to be useful in studying type systems
of programming languages, which is where most of my exposure to them
has come from.

> But let me try an example to see if I've got it right:
> class Int2StrFunctor:
>     def map1(self, n):
>         if type(n) is not int:
>             raise TypeError('argument must be an int')

I don't think this is right.  A functor (in the PL sense that I've
been describing) acts on types, not on members of types.  That is,
your example turns "3" into "---", i.e. it turns a member of type
"int" into a member of type "str".  A functor would be something that
acts on arbitrary types, e.g. one might turn "int" into "array of
int", and "str" into "array of str" and so forth.  Another might turn
"int" into "red-black tree containing a pair of ints at each node" and
doing something similar with str.  The map1 and map2 functions (I
guess it is ok to call them that) are supposed to be generic.

I guess you could have a "String" functor whose map1 function is repr
and whose map2 functor is (lambda f: lambda x,f=f: repr(f(x))) or
something like that.  It would transport every type to the str type.

> There are some technical restrictions on functors, relating to the sorts
> of functions and types (strictly "categories") they can accept,
> presumably to make them mathematically well-behaved.

Right.

```