Introduction to Functors in C#

Let me tell you what functor is right now for OOP : It’s a container. together with a mapping function.

Functor are the base of category theory which have become one of the most valuable tools of functional programming paradigm. Also c# is becoming more and more functional. C# developers should be familiar with the functional paradigm.

In mathematics, a functor is a map between categories. A category is just a collection of objects and arrows between objects like below. Category c has the objects x,y and an arrow f from x to y. That's all there is to it basically. kind of.

In Programming one major category is this of Types. The arrows between the types are the functions/methods. But because the concept is so broad, categories arise in all kind of areas inside programming. For example If we get the category where objects are programs then the arrows between them could be Compilers, that get an input program and give a different program. A parenthesis here. My absolute favorite book in this topic is Computability and Complexity: From a Programming Perspective also Neil has a free pdf here.

Ok, lets get back to Functors. A functor F just maps objects from C, to an other category D.

A generic implementation of Functor

lets get straight to the point and see an example in c#. The List is a Functor together with the Select method. The select is the method that maps or as we say lift a function f from the initial category.

In the following example we have the integers 2 and 4 (lets say for simplicity the category of integers for this example) also in this category there is the function f(x)=x+2 that maps 2 to 4. If we apply the list functor the mapping of 2 to a List category would be simply the singleton list new List {2 } and for 4 the singleton list new List{4 } the only part missing is the correct lifting of the function f to this new category. Its easy to see that the correct mapping is the Select(x=>f(x))

Commutative Diagrams

There is one important thing about the mapping function.

diagram commutes when F(f) ○ F = F ○ f

The mapping should get the same result for [4] if we take any of the two possible routes to get there. This means :

Map (aka lifting of a function from C to D) should Preserve Structure

1)We could first get the list and then map the list. This is the red path on the diagram.

var paht1 = new List{2}.select(x => x + 2)

2)or first add 2 and then get the list .

Func<int, int> add2=x => x + 2;var path2 = new List<int> { add2(2) };

We say that the diagram commutes when this is the case. And that means that the lifting of morphisms (aka arrows aka functions in programming) preserves the structure of the objects in C.

The Task Functor

In the example below just take an integer and wrap it in a Task<int> with Task.Run(()=>2) . But also there has to be a mapping function that would be able to lift any function that acts on integers.

one such mapping function, for integers could be the following :

Here the mapping function that lifts the function f :int->int just waits for the result of the Task ( so in a way unwraps the contained value ) then apply the function f and then wraps again the resulting value into a new task in order to return a something that belongs to the same category (in this case type) or Task.

Keep that in mind because its a common theme among Monads in which Promise/Task belongs. Also if you are familiar with GoF design patterns this resembles a decorator in the sense that Mapping returns an Object with the same signature but where additional operations where applied.

and The book “ Functional Programming in C#



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store