If you don't have exceptions and you don't have null : How do you handle errors and invalid inputs? Based on your background, this can either be trivial or

mind-bending. Coming into the Haskell (actually: Elm and Rust) world from C#, JavaScript, and Python, it definitely wasn't obvious to me at first.

Luckily, the Maybe and Either types are there for you, and they are fairly

easy to get started with. In this post, I want to give a quick introduction to both of these data types and how they're used.

To any returning readers: This post is based chapter 12 of /Haskell Programming from First Principles/, which deals with basic error handling in Haskell, using the ~Maybe~ and ~Either~ types. The chapter doesn't actually introduce much else of interest, so I wanted to approach this entry slightly differently.

What we will (and won't) be covering This post is intended to be a brief introduction to the Maybe and Either data types in Haskell; suitable for someone who has no previous experience with these. Some understanding of Haskell syntax would be beneficial, but is not required. The post should give the reader a basic understanding of what Maybe and Either are and how they can be used for modeling data and responses. This post is not intended to be a thorough examination of these types. It will not discuss anything related to typeclasses, mapping, or binding. There will also not be any extensive code samples. As such, please note that there is a lot more to these data types than we will look at here, but that most of it is out of scope for this post. For further reading, please consult the section at the end of the article.

Maybe Maybe represents the potential absence of a value. It is used when some data can be in one of two states: defined/present, or undefined/absent. Because Maybe represents a value that may or may not be present, we also need to specify the type of the potentially contained item: Maybe String , Maybe Integer , or Maybe a for instance. In many ways, Maybe is similar to null in C#, JavaScript, etc., None in Python, and related concepts (like nil ) in a lot of other languages. However, in these other languages, the potential lack of a value is (almost) always implicit, meaning the programmer can never be sure whether the value is there or not. In Haskell, this is always explicit. The Maybe type is the same as the Option type in languages like Rust and F#. The data declaration looks a little something like this: data Maybe a = Nothing | Just a As such, Maybe has two data constructors, Nothing and Just , where the latter takes a value to wrap. Basic usage While there's any number of ways you can use the Maybe type in your programs, I find the two most obvious ways to be to model data where some parts are optional to return something from a function if the input is invalid Being able to indicate that a value may or may not be present is a simple, but very powerful tool of modeling data. Imagine you've created a dating app for Haskellers---let's call it Hinder---where you want to display a list of users. The list should display only their profile picture and their name, but there's no requirement to have set a profile picture to be listed, so we'll need to account for that. A simplistic way to model that would be by using a list of records like this: data User = User { name :: String , picture :: Maybe String } Where the picture value is Nothing if there is no profile picture set. If they have a profile picture, it's Just <picture id> . The other way to use Maybe is as the return value of a function. As much as possible, you should use the type system to constrain the set of allowed arguments to a function, but that'll only get you so far. The built-in div function throws an exception if you pass 0 as the second argument, so let's fix that by using Maybe . If the divisor is 0 , return Nothing . Otherwise, return Just <result> . safeDiv :: Integral a => a -> a -> Maybe a safeDiv _ 0 = Nothing safeDiv x y = Just $ x ` div ` y