Reporting Errors with Either
Introduction: From "Nothing" to "Why"
Welcome to the fifth unit of our course! In our previous lesson, you learned how to handle missing data safely using Haskell's Maybe type. You practiced returning Nothing when a task couldn't be found and returning Just task when the search was successful.
While Maybe is fantastic for handling absence, it has a limitation: it cannot tell us why an operation failed. Returning Nothing is like a package delivery status that simply says "Not Delivered." As a user, you would much rather see a status that says "Invalid Address" or "Lost in Transit," so you know exactly what went wrong.
When you need to know the reason for a failure, Haskell provides a built-in type called Either. The Either type has two possible states, or constructors: Left and Right. By standard convention in Haskell, the Right constructor holds the "right" or successful answer, while the Left constructor holds the error message or reason for failure.
In this lesson, we are going to upgrade our task manager to reject invalid task IDs (like negative numbers) and explain exactly why the input was rejected.
Validating Data with Either
Let's begin by writing a function that checks if a user's requested ID is valid. We will call this function validateId.
First, let's look at the type signature:
As you recall from our first unit on naming your domain, TaskId is simply a descriptive alias for an Int. Our function takes this TaskId and returns an Either type. This Either will contain a String if it fails (the error message) or a TaskId if it succeeds.
Now, let's implement the logic to check if the ID is less than 1.
Using standard Haskell guards, we check if tid is less than 1. If it is, the ID is invalid. We return our helpful error string wrapped inside the Left constructor to signal a failure.
Next, we handle the success case:
If the ID is 1 or greater, we fall through to the otherwise condition. Here, we wrap the valid ID in the Right constructor, safely passing it along for the next step in our program.
