# Reactive functor by Mark Seemann

*IObservable<T> is (also) a functor.*

This article is an instalment in an article series about functors. While the previous articles showed, in great detail, how to turn various classes into functors, this article mostly serves as a place-holder. The purpose is only to point out that you don't have to create all functors yourself. Sometimes, they come as part of a reusable library.

Rx is such a library, and `IObservable<T>`

is a functor. (It's also a monad, but this is not a monad tutorial; it's a functor tutorial.) Reactive Extensions define a `Select`

method for `IObservable<T>`

, so if `source`

is an `IObservable<int>`

, you can translate it to `IObservable<string>`

like this:

IObservable<string> dest = source.Select(i => i.ToString());

Since the `Select`

method is, indeed, called `Select`

and has the signature

public static IObservable<TResult> Select<TSource, TResult>( this IObservable<TSource> source, Func<TSource, TResult> selector)

you can also use C#'s query syntax:

IObservable<string> dest = from i in source select i.ToString();

In both of the above examples, I've explicitly declared the type of `dest`

instead of using the `var`

keyword. There's no practical reason to do this; I only did it to make the type clear to you.

### First functor law #

The `Select`

method obeys the first functor law. As usual, it's proper computer-science work to actually prove that, but you can write some tests to demonstrate the first functor law for the `IObservable<T>`

interface. In this article, you'll see a few parametrised tests written with xUnit.net. Here's one that demonstrates that the first functor law holds:

[Theory] [InlineData(-101)] [InlineData(-1)] [InlineData(0)] [InlineData(1)] [InlineData(42)] [InlineData(1337)] public async Task ObservableObeysFirstFunctorLaw(int value) { var sut = new[] { value }.ToObservable(); IObservable<int> projected = sut.Select(x => x); var actual = await projected.FirstAsync(); Assert.Equal(value, actual); }

Here, I chose to implement the identity function as an anonymous lambda expression. In contrast, in a previous article, I explicitly declared a function variable and called it `id`

. Those two ways to express the identity function are equivalent.

As always, I'd like to emphasise that this test doesn't *prove* that `IObservable<T>`

obeys the first functor law. It only demonstrates that the law holds for those six examples.

### Second functor law #

Like the above example, you can also write a parametrised test that demonstrates that `IObservable<T>`

obeys the second functor law:

[Theory] [InlineData(-101)] [InlineData(-1)] [InlineData(0)] [InlineData(1)] [InlineData(42)] [InlineData(1337)] public async Task ObservableObeysSecondFunctorLaw(int value) { string g(int i) => i.ToString(); string f(string s) => new string(s.Reverse().ToArray()); var sut = new[] { value }.ToObservable(); IObservable<string> projected = sut.Select(i => f(g(i))); var actual = await projected.FirstAsync(); var expected = await sut.Select(g).Select(f).FirstAsync(); Assert.Equal(expected, actual); }

This test defines two local functions, `f`

and `g`

. Instead of explicitly declaring the functions as `Func`

variables, this test uses a (relatively) new C# feature called local functions.

Again, while the test doesn't prove anything, it demonstrates that for the six test cases, it doesn't matter if you project the observable in one or two steps.

### Summary #

The point of this article is mostly that functors are commonplace. While you may discover them in your own code, they may also come in a reusable library. If you already know C# LINQ based off `IEnumerable<T>`

, much of Rx will be easy for you to learn. After all, it's the same abstraction, and *familiar abstractions make code readable*.

**Next:** The Identity functor.