The Validation Course

The course begins with two lessons on case expressions to ensure a solid foundation. From there, we write three functions for checking that inputs are valid passwords according to the rules of our system. The rest of the lessons iteratively expand on and refactor those functions into a small program that validates usernames and passwords, constructs a User if both are valid inputs, and returns pretty error messages if they are not. Along the way we learn about Monad and Applicative and how they are similar and different and how to use types to rethink our solutions to problems.

Lesson descriptions

  • Lesson 1: Introduction to case expressions

    The first lesson takes a look at conditional if-then-else expressions in Haskell and compares them to a similar pattern with different syntax: case expressions.

  • Lesson 2: Case expressions practice

    This lesson works through an example to see how case expressions allow us to branch, like conditionals, on values other than booleans – specifically, working with Maybe to distinguish different kinds of false-ness.

  • Lesson 3: Validation functions

    In this lesson, we begin writing the code that will be extended and refactored throughout the rest of the course. We write three functions that check String inputs against length and character requirements and check for and strip off leading whitespace.

  • Lesson 4: The Maybe Monad

    The last lesson left you with an exercise to do. This lesson leads off with two solutions to that exercise and introduces an operator, >>=, that can reduce nested case expressions with Maybe into a concise composition.

  • Lesson 5: Refactoring with Either

    We change from using Maybe to using another sum type called Either to see if that helps solve some of the issues we have noticed in our code so far.

  • Lesson 6: Working with newtypes

    Our code is now looking pretty good, but we want to extend it to include validation of user name inputs as well as to construct a User that is a product of a username and a password. We also introduce newtypes here so that we can distinguish between passwords, errors, and usernames at the type level.

  • Lesson 7: Introducing Applicative

    In this lesson we find that using Either and our newtypes introduces a need to alter some of our expressions, and we will use operators from the Applicative typeclass to help us with that.

  • Lesson 8: Refactoring with Validation

    This lesson introduces the validation library and the Validation type. Although Validation is very similar to Either, the differences force us to change our code significantly, as Validation cannot be a Monad. We’ll talk about why not and step through all the ramifications for our code.

  • Lesson 9: Better Error Messages

    We are now accumulating and returning informative error messages about which inputs are invalid and why, but this lesson introduces a couple extra steps to tidy them up for presentation to our users.


This course assumes very little prior knowledge of Haskell. We are focused here on working through examples without understanding theory or how and why things work too deeply. This course has goals and an approach similar to Julie’s famous blog postThe Nesting Instinct


We do use recursion in one function without explaining it fully. We also rely on and derive instances for several typeclasses without explaining what typeclasses are or how they work; how they work is briefly discussed during lesson 8 when we need to write an instance of Semigroup.

Show notes

  • Instructor: Julie Moronuki
  • Window manager: xmonad
  • Text editor: Atom with the language-haskell package
  • Font: Ubuntu Mono (editor and terminal)
  • Syntax theme: Ficus Light in Atom; terminal has a custom color scheme based off Ficus DarkFind out more about the Ficus themes here!

  • GHCi note: My GHCi configuration has :set +t on all the time. The +t option tells you the type of an expression you enter at the prompt. It is what displays the type of it after I evaluate an expression as in the third line here:
λ> isAnagram "julie" "eiluj"
it :: Bool

That is not something GHCi does by default, so if yours doesn’t do it, don’t worry about it. You can turn this on in your GHCi if you want by entering :set +t at the prompt, but it won’t affect anything we’re doing in this course.

There are also some language extensions I keep turned on in my GHCi config most of the time; you’ll learn about one of these, -XTypeApplications, in lesson 4.