# Fantas, Eel, and Specification 10: Alt, Plus, and Alternative

We’re in double digits! Isn’t this exciting? It also means that, by my estimations, we’re well over half way! Before we get too excited by `Profunctor` and `Comonad`, though, might I tempt you with an… `Alternative`?

Today, we’re going to bundle together three very well-related entries in the spec, starting with `Alt`. This little typeclass has one function:

``````alt :: Alt f => f a ~> f a -> f a
``````

As we know, with great algebraic structure, come great laws:

``````// Associativity
a.alt(b).alt(c) === a.alt(b.alt(c))

// Distributivity
a.alt(b).map(f) === a.map(f).alt(b.map(f))
``````

The associativity law is exactly what we saw in the `Semigroup` post with `concat`! As we said back then, think of it as, “Keeping left-to-right order the same, you can combine the elements however you like”.

Distributivity gives us another clue that we might be looking at something a bit `Semigroup`-flavoured. We can `map` first over the elements and then `alt` or `alt` first and then `map` over the result, and we’ll end up at the same value. Either way, some kind of “combination” definitely seems to be going on here.

So, what is it? Well… it’s like a semigroup for functors. It’s a way of combining values of a functor type without the requirement that the inner type be a `Semigroup`. Why, you ask? Well, we get a little hint from the name.

`Alt` allows us to provide some alternative value as a “fallback” when the first “fails”. Of course, this is particularly relevant to types with some notion of failure:

``````Maybe.prototype.alt = function (that) {
this.cata({
Just: _ => this,
Nothing: _ => that
})
}
``````

If we have a `Just` on the left, we return it. Otherwise, we fall back to the second value! Naturally, you can chain as many of these as you like:

``````// Just(3) - note the "Nothing"s are
// usually the result of some functions.
Nothing.alt(Nothing).alt(Just(3))
``````

It turns out there are loads of use cases for `alt`, which isn’t too surprising if you look at it as a functor-level `if/else`. You can do database connection failover, API/resource routing, and, most magically of all, text parsing. Those last two were in PureScript and Haskell respectively, but don’t worry: in these languages, `alt` has an operator, written as `<|>`.

The key thing all these cases have in common is that you want to try something with a contingency plan for failure. That’s all there is to `Alt`!

If `Alt` will be our functor-level `Semigroup`, what’s our functor-level `Monoid`? In comes `Plus`, which extends `Alt` with one more function called `zero`:

``````zero :: Plus f => () -> f a
``````

Looks a bit like `Monoid`’s `empty`, right? Note that there’s no restriction on the `a`, so this `zero` value must work for any type. This one has three laws, but the first two will look really familiar to readers of the `Monoid` post:

``````// Right identity - zero on the right
x.alt(A.zero()) === x

// Guess what this one's called?
A.zero().alt(x) === x

// The new one: annihilation
A.zero().map(f) === A.zero()
``````

The left and right identity laws just say, “`zero` makes no difference to the other value, regardless of which side of `alt` you put it”. Annihilation gives us a stronger idea of what `zero` does: nothing! `Plus` types must be functors; for a `map` call to do nothing in all cases, the type must have the ability to be empty, whatever that means.

Think of our `Maybe` type: what can we `map` over with any function and not change the value? `Nothing`! In fact, `() => Nothing` is the only valid implementation of `zero` for `Maybe`.

What about `Array`? Well, `map` transforms every value in the array, so the only array that wouldn’t be changed is the empty one. `() => []` is the only valid implementation of `zero` for `Array`.

We didn’t cover `Array` as an `Alt` because it’s a bit of a funny one. Back when we discussed functors, we saw that `Array` extends our language to allow us to represent several values at once. This can be thought of as non-determinism if we see an `Array` as the set of possible values. Thus, the `alt` implementation for `Array` is the same as `concat` - all we’re doing is combining the two sets of possibilities!

So, `Plus` adds to `Alt` what `Monoid` adds to `Semigroup`, and, in fact, what `Applicative` adds to `Apply`: an identity. Are we bored of this pattern yet? I hope not, because we’re still not done with it! Incidentally, we can write custom `Semigroup` and `Monoid` types to encapsulate this behaviour so we can reuse the functions we talked about in their posts:

``````// The value MUST be an Alt-implementer.
const Alt = daggy.tagged('Alt', ['value'])

// Alt is a valid semigroup!
Alt.prototype.concat = function (that) {
return Alt(this.value.alt(that.value))
}

// The value MUST be a Plus-implementer.
// And, as usual, we need a TypeRep...
const Plus = T => {
const Plus_ = daggy.tagged('Plus', ['value'])

// Plus is a valid semigroup...
Plus_.prototype.concat =
function (that) {
return Plus(
this.value.alt(
that.value))
}

// ... and a valid monoid!
Plus_.empty = () => Plus_(T.zero())
}
``````

Monoids are everywhere, I tell you. Stare at something long enough and it’ll start to look like a monoid.

The final boss level on this `Alt` quest is `Alternative`. There are no special functions for this one, as it is simply the name for a structure that implements both `Plus` and `Applicative`. Still, I know how much you love laws:

``````// Distributivity
x.ap(f.alt(g)) === x.ap(f).alt(x.ap(g))

// Annihilation
x.ap(A.zero()) === A.zero()
``````

Distributivity is exactly as the same law that we saw with `Alt` and `map` at the beginning of all this, but now for `ap`. We can either `alt` first and then `ap` the result to `x`, or we can `ap` first to both separately, and then `alt`. Either way, we end up in the same place.

Annihilation is a really scary word for a not-so-scary idea, if you think back to the `zero` values we discussed earlier. You couldn’t apply a value to `Nothing`, right? Or an empty list of functions? The annihilation law defines this behaviour: if you try to do something with nothing, you get nothing. Whatever you were doing is considered a failure, and `zero` is returned.

You’ll often hear `Alternative` types described as monoid-shaped applicatives, and this is a good intuition. We talked about `of` as being the identity of `Applicative`, but this is only at context-level. For an `Alternative` type, `zero` is the identity value at context- and value-level.

`Maybe`, `Array`, `Task`, `Either`: we’ve seen a lot of types that can very naturally implement `Alternative`. You could even make `Function` an `Alternative` if you knew the output would be of a `Plus`-implementing type. With that, you could then write a function whose body can do extra computation depending on the result; who needs `if/else`?

That’s about all there is to it! `Alt`, `Plus`, and `Alternative` are under-appreciated typeclasses, particularly within functional JavaScript. Take some time to look through your code, glare at the `if/else`, `try/catch`, and `switch` blocks, and see whether they’re really just `alt`s in disguise!

Next time, we’ll be looking into your new favourite typeclasses: `Foldable` and `Traversable`. Try to contain your excitement until then!

Take care ♥