#readwise
# Functors

## Metadata
- Author: [[Mark Seemann]]
- Full Title: Functors
- URL: https://blog.ploeh.dk/2018/03/22/functors/
## Summary
This is article is a part of a bigger blog series that covers various topics from category theory. The series includes other articles on the topic of functors. Here's a list, retrieved on March 17, 2023.
- The Maybe functor
- An Either functor
- A Tree functor
- A rose tree functor
- A Visitor functor
- Reactive functor
- [[The Identity functor]]
- The Lazy functor
- Asynchronous functors
- The State functor
- The Reader functor
- The IO functor
- Monomorphic functors
- Set is not a functor
## Highlights
- **Perhaps the most well-known of all functors is List, a.k.a. Sequence. C# query syntax can handle any functor, but most people only think of it as a language feature related to `IEnumerable<T>`. ... If you understand how LINQ, `IEnumerable<T>`, and C# query syntax works, however, all other functors should feel intuitive. That's the power of abstractions.**
- In short, **a functor is a mapping between two categories. A functor maps not only objects, but also functions (called morphisms) between objects**. For instance, a functor F may be a mapping between the categories C and D:
![[functor-diagram.png|250]]
Not only does F map a from C to F a in D (and likewise for b), it also maps the function f to F f. **==Functors preserve the structure between objects.== You'll often hear the phrase that a functor is a structure-preserving map. ==One example of this regards lists. You can translate a `List<int>` to a `List<string>`, but the translation preserves the structure. This means that== the resulting object is also a list, and ==the order of values within the lists doesn't change==.** ^is51dg
- In category theory, categories are often named C, D, and so on, but an example of a category could be `IEnumerable<T>`. If you have a function that translates integers to strings, the source object (that's what it's called, but it's not the same as an OOP object) could be `IEnumerable<int>`, and the destination object could be `IEnumerable<string>`. A functor, then, represents the ability to go from `IEnumerable<int>` to `IEnumerable<string>`, and since the Select method gives you that ability, `IEnumerable<T>`.Select is a functor. **In this case, you sort of 'stay within' the category of `IEnumerable<T>`, only you change the generic type argument, so this functor is really an endofunctor (the endo prefix is from Greek, meaning within).**
- Fundamentally, you must be able to implement a method for your generic type that looks like this:
`public Functor<TResult> Select<TResult>(Func<T, TResult> selector)`
Here, I've defined the Select method as an instance method on a class called `Functor<T>`, but often, as is the case with `IEnumerable<T>`, the method is instead implemented as an extension method. **You don't have to name it Select, but doing so enables query syntax in C#**:
```csharp
var dest =
from x in source
select x.ToString();
```
Here, source is a `Functor<int>` object.
If you don't name the method Select, it could still be a functor, but then query syntax wouldn't work. Instead, normal method-call syntax would be your only option. This is, however, a specific C# language feature. **F#, for example, has no particular built-in awareness of functors, although most libraries name the central function map.**
- The common trait is that there's an input value (`Functor<T>` in the above C# code snippet), which, when combined with a mapping function (`Func<T, TResult>`), returns an output value of the same generic type, but with a different generic type argument (`Functor<TResult>`).
- **Defining a Select method isn't enough. The method ==must also obey the so-called functor laws==.** These are quite intuitive laws that govern that a functor behaves correctly.
**==The first law is that mapping the identity function returns the functor unchanged==. The identity function is a function that returns all input unchanged.** (It's called the identity function because it's the identity for the endomorphism monoid.) In F# and Haskell, this is simply a built-in function called id. ... **==The second law states that if you have two functions, f and g, then mapping over one after the other should be the same as mapping over the composition of f and g==.** ^ms2vt9