# Builder as Identity by Mark Seemann

*In which the Builder functor turns out to be nothing but the Identity functor in disguise.*

This is the fourth in a series of articles about the relationship between the Test Data Builder design pattern, and the identity functor. In the previous article, you saw how a generic Test Data Builder can be modelled as a functor.

You may, however, be excused if you're slightly underwhelmed. Modelling a Test Data Builder as a functor doesn't seem to add much value.

### Haskell's Identity functor #

In the previous article, you saw the Builder functor implemented in various languages, including Haskell:

newtype Builder a = Builder a deriving (Show, Eq) instance Functor Builder where fmap f (Builder a) = Builder $ f a

The `fmap`

implementation is literally a one-liner: pattern match the value `a`

out of the `Builder`

, call `f`

with `a`

, and package the result in a new `Builder`

value.

For many trivial functors, it turns out that the Glasgow Haskell Compiler (GHC) can automatically implement `fmap`

with a language extension:

{-# LANGUAGE DeriveFunctor #-} module Builder where newtype Builder a = Builder a deriving (Show, Eq, Functor)

Notice the `DeriveFunctor`

language extension. This enables the compiler to automatically implement `fmap`

by adding `Functor`

to the `deriving`

list.

Perhaps we should take this as a hint. If the compiler can automatically make `Builder`

a `Functor`

, perhaps it doesn't add that much value.

This particular `Builder`

is equivalent to Haskell's built-in `Identity`

functor. `Identity`

is a 'no-op' functor, if you will. While it's a functor, it doesn't 'do' anything. It's similar to the Null Object design pattern, in the sense that the only value it adds is that it enables you to turn any naked value into a functor. This can occasionally be useful if you need to pass a functor to an API.

### PostCode and Address builders #

You can rewrite the previous `PostCode`

and `Address`

Test Data Builders as `Identity`

values:

postCodeBuilder :: Identity PostCode postCodeBuilder = Identity $ PostCode [] addressBuilder :: Identity Address addressBuilder = Identity Address { street = "", city = "", postCode = pc } where Identity pc = postCodeBuilder

As in the previous examples, `postCodeBuilder`

is nothing but a 'good' default `PostCode`

value. This time, it's turned into an `Identity`

value, instead of a `Builder`

value. The same is true for `addressBuilder`

- notice that it uses `postCodeBuilder`

for the `postCode`

value.

This enables you to build an address in Paris, like previous examples:

Identity address = fmap (\a -> a { city = "Paris" }) addressBuilder

This builds an address with `city`

bound to `"Paris"`

, but with all other values still at their default values:

Address {street = "", city = "Paris", postCode = PostCode []}

You can also build an address from an `Identity`

of a different generic type:

Identity address' = fmap newAddress postCodeBuilder where newAddress pc = Address { street = "Rue Morgue", city = "Paris", postCode = pc }

Notice that this example uses `postCodeBuilder`

as an origin, but creates a new `Address`

value. In this expression, `newAddress`

is a local function that takes a `PostCode`

value as input, and returns an `Address`

value as output.

### Summary #

Neither F# nor C# comes with a built-in identity functor, but it'd be as trivial to create them as the code you've already seen. In the previous article, you saw how to define a `Builder<'a>`

type in F#. All you have to do is to change its name to `Identity<'a>`

, and you have the identity functor. You can perform a similar rename for the C# code in the previous articles.

Since the Identity functor doesn't really 'do' anything, there's no reason to use it for building test values. In the next article, you'll see how to discard the functor and in the process make your code simpler.

**Next:** Test data without Builders.