# Traces with monoidal errors

Haskell has a lot to offer when it comes to cleaning up your code structure. One of the gains is proper error signaling. Let us look at common C code returning `NULL`

to signal errors and setting a global error variable:

```
void \*foo(...) {
do_something();
if (error) {
errno = 42;
return NULL;
} else {
return result;
}
}
```

You will find this for example in the standard function `fopen`

. Additionally a global variable `errno`

is set, to signal which kind of error was encountered. While this is very straight forward it has two problems:

- You are not warned if you use the result without checking for an error
- The global variable
`errno`

will be overwritten on every call

Now most modern languages solve this by adding Exceptions as a controlflow escape mechanism. They are as common place as shun upon, since they can cause great headaches in compiler construction, reasoning about code, multithreading, maintainability and cleanup.

A lot has been done in the Haskell world to study the subject. One of the most common approaches in real world libraries is to use MonadError with `(Error e) => Either e a`

. We all know, that this is most convenient, especially because of the do-notation to chain computations which can fail:

```
foo :: Either String Result
foo = do
x <- bar
y <- baz x
return y
```

`Either`

also is the Haskell name for coproducts,

which means

```
recover = either recover use . Left
use = either reover use . Right
```

Where either is the unique function

```
either f _ (Left x) = f x
either _ g (Right y) = g y
```

and equality is up to Haskell’s reduction and alpha renaming. If an initial neutral element exists, coproducts can be turned into monoids. This element exists for the typeclass `Error`

because of `noMsg : (Error e) => e`

.

```
instance (Error e) => Monoid (Either e a) where
mempty = Left noMsg
(Left _) `mappend` x = x
res@(Right _) `mappend` _ = res
```

Combined with the monadic properties, this can as well be expressed as a `MonadPlus`

instance. It is well known, that this interface allows elegant backtracking

```
backtrack :: (Error e) => [Either e a] -> Either e a
backtrack = foldl1 mappend
```

`backtrack`

returns the first computation that did not fail. However the amiable reader might have noticed that the second problem mentioned above is not solved:

```
(Left err1) `mappend` (Left err2)
```

will drop `err1`

and only return `err2`

. Luckily there is an easy improvement on the `Monoid`

(or `MonadPlus`

) instance of `Either `

. What is really missing is a way to combine multiple errors and preserve the monoid properties. The easiest way to obtain the missing piece is to add a monoid requirement on the error type argument:

```
instance (Error e, Monoid e) => Monoid (Either e a) where
mempty = Left mempty
(Left e1) `mappend` (Left e2) = Left (e1 `mappend` e2)
(Left e1) `mappend` res@(Right _) = res
res@(Right _) `mappend` _ = res
```

Even though this approach is most simplistic, it just works :). Error types for which no combination is available can easily resort to the standard behavior:

```
instance Monoid StandardError where
mempty = Left noMsg
err `mappend` _ = err
```

A full blown instance declaration (including a monad transformer to stack the new error mechanism) can be found here. Let me know, if you need anything else (more instances, an upload to hackage, …).