either functions in Scala and Haskell

posted: 2013-Apr-08

In some of the languages I work in, we have a data type called Either that’s used to carry two types of data in a container to give them a common type. It’s a kind of disjoint union. This type is useful for a variety of things including meaningful error information about a computation that may fail.

In Haskell, the type looks like this:

-- Haskell
data Either a b
    = Left a
    | Right b

The definition of this type is a bit more complicated in Scala so I won’t show it here, it’s very much the same idea though.

So, imagine some code that returns an (Either String Int), we can switch on the shape of the data to interpret what happened:

-- Haskell
case someFunction of
    Left errMsg -> -- do something with this error message
    Right value -> -- do something with the "right" value

Something similar in Scala would go like this:

// Scala
match someFunction() {
    case Left(errMsg) => // do something with this error message
    case Right(value) => // do something with the "right" value
}

And that’s great, but it would be more functional and useful to have a higher-order function. One that takes an Either and two functions, a left-handler and a right-handler.

Scala and Haskell both have this covered, but let’s imagine for a minute that neither of these languages has the function and we’d like to write one.

So let’s start with the Scala, we want this to be a polymorphic function, for any types we can plug into an Either, so it could look like this:

// Scala
def either [A, B, C] (f: (A) => C) (g: (B) => C) (e: Either[A, B]): C =
    match e {
        case Left(x)  => f(x)
        case Right(y) => g(y)
    }

Basically this is a convenience function doing the same pattern match as earlier. Also, I deliberately wrote this function in the way that permits partial evaluation, it’s just more useful that way. This is at the expense of a noisier calling syntax: either (lfunc) (rfunc) (someEither) You get this behavior with every function in Haskell ‘for free.’

Now for Haskell:

-- Haskell
either f _ (Left x)  = f x
either _ g (Right y) = g y

That’s it, those two lines right there are a complete definition. In Haskell, we can express the cases right in function bodies, eliminating the need to bind the Either to some identifier we’ll barely use at all.

If you want to be conscientious and include the optional type signature, that’s less noisy as well. And notice we don’t need to separately list the type variables a, b and c, as is necessary in the Scala:

-- Haskell
either :: (a -> c) -> (b -> c) -> Either a b -> c

This is just one small example of the many things that Haskell is very good at. I think the clarity here is important. As a project gets more complex, it helps everyone for the code to be this clean and expressive.