FizzBuzz Kata: An Exploration With Functors
By: Mathieu Eveillard
Tags: Programming, JavaScript, Fizzbuzz, Web Development, Functor

FizzBuzz

FizzBuzz is a well-known kata in the Crafts community, because it’s perfectly suited to learning Test Driven Development (TDD), as it is simple and progressive, while allowing more than one refactoring.

The purpose here though is not to learn TDD, hence we’ll jump directly to a good-enough implementation. The tests and the source code are available on GitHub.

In real life, I would stop there: it works, it’s simple, it’s legible.

But… I’m not quite satisfied yet. The gut feeling is that the implementation relies on a pipe:

Initialise the result with an empty string

Append “Fizz” if the number is a multiple of 3

Append “Buzz” if the number is a multiple of 5

Finally append the number as a string if it is not a multiple of 3 nor 5

Though, I don’t see it in the code: one cannot read it as a sentence in plain English, probably because of the mutable state ( let result ).

I wish I could build a pipe by composing pure functions and feed the pipe with an initial empty string. That means, in pseudo code:

"".map(appendFizzIfNIsMultipleOf3(n))

.map(appendBuzzIfNIsMultipleOf5(n))

.map(returnNOtherwise(n))

Unfortunately, the String prototype doesn’t expose a map method. That’s where functors come into play.

Unfortunately, the String prototype doesn’t expose a map method. That’s where functors come into play.

Functors

For a great introduction to functors, you may want to refer to Eric Elliott’s Composing Software book (Functors & Categories chapter). But I suggest you read it after reading this use case. The key takeaway is that a functor is a mappable type, that is a type that exposes a map method.

A functor is a mappable type.

So basically, we’re going to wrap the empty string in a functor, do mappings and then unwrap the functor to return the modified string it carries.

We can refactor safely thanks to the unit tests that helped us building the first implementation. So without further ado, let’s jump right in!

Wow… So much code for such a small feature! This might be over-engineered, but we’ll go with it since it’s for demonstration purpose only.

Let’s see what happens here:

First we define the functor, through its constructor IdentityFunctor . It encapsulates a value of a given type (e.g. a string) and can be mapped to an IdentityFunctor , whose type is determined by the mapping function fn . Here however, we’ll only map from string to string.

. It encapsulates a of a given type (e.g. a string) and can be mapped to an , whose type is determined by the mapping function . Here however, we’ll only map from string to string. Then we define pure mapping functions, appendIfMultipleOf and returnNOtherwise , that encapsulate most of the business logic (the word is too big for that, but hey, you see what I mean).

and , that encapsulate most of the business logic (the word is too big for that, but hey, you see what I mean). And at last has come the time when we can use those foundations: in 5 lines of code, it is now crystal clear that we build upon an empty string by concatenating things under certains conditions and return the result. It’s almost plain English.

Additional notes: