To handle errors (or exceptions), most languages have implemented the try/catch instruction, which is wacky in more ways than one.
First, it’s syntactically strange. We are incitated to focus on the successful execution path, as if the catch instruction was ‘just in case something bad might happen’.
We never write code like this in other situation. We never assume a value is equal to another, we first check that assumption in an if or a match. In the same logic, we should never assume that our code will always work.
Moreover, in some languages such as TypeScript, we can’t even declare what kind of error we can throw, making the type safety in a catch block simply non-existent.
The solution: Use the Result monad
The Result monad is a generic type (but really an union under the hood) that will force you to handle errors by wrapping your return types.
Type definition
Constructor
Err
A Result representing a failure can be constructed with the Err function.
Ok
A Result representing a success can be constructed with the Ok function.
Methods
The Result monad exposes several methods to unwrap its value.
You can see a usage of each method in the example section below.
map
The map method allows you to map the success state of a Result to a new value.
flatMap
The flatMap method allows you to map the success state of a Result to a new Result.
flatMapAsync
The flatMapAsync method allows you to map the success state of a Result to a new AsyncResult.
mapErr
The mapErr method allows you to map the failure state of a Result to a new value.
filter
The filter method allows you to map a success state to a failure state if a condition isn’t met.
filterType
The filterType method allows you to map a success state to a failure state if a condition isn’t met, while narrowing the type of the success state.
toMaybe
The toMaybe method allows you to map a Result to a Maybe monad.
toLoading
The toLoading method allows you to map a Result to a Loading monad.
Result and pattern matching
Result is an union, which means you can handle it with match.
Examples
Let’s make a function that divides 2 number and can return an error: