Case expressions are useful for conditionals that have multiple branches. As mentioned on the previous page, pattern guards can also be used to a similar effect.

This program uses the time package for handling time conversions.

The branches are introduced once by case...of. Haskell doesn’t typically use curly braces, but the of is necessary and the indentation matters.

The values on the left side of the -> arrows are the cases of the type that the expression in case <exp> of evaluates to. The < function returns a Boolean, so this an alternate to if expressions but with explicit matching.

case expressions can be used to match on the values of a custom datatype. Here is a custom type representing three mutually exclusive service plans.

The billAmount function associates a ServicePlan value to a numeric value.

Some types have more values than you want to match on manually, and maybe some of the possible inputs are irrelevant to your needs. An underscore in the final case is a catchall that will match against any value.

You can use those functions in a main program by declaring some variables and applying the functions to them within the do-block. This is what runhaskell will run (see below).

Let’s use the REPL to check our work. Passing the filename you want to load into the GHCi session ensures that all the things you need are in scope at the start of your session.

GHCi can give lots of information about programs. This session demonstrates applying single functions to appropriate arguments.

If you try applying billAmount to a number, or writeNumber to a Boolean, GHCi will become annoyed. Displayed here are the first lines of the error messages you’d receive for these examples. Both of them are conveying the information that neither ServicePlan values nor Bool values are numbers, so they cannot be used interchangeably with numbers.

The >>= function can be thought of as a means of passing the output of the first function, getZonedTime, to a second function. The first example only prints the output of getZonedTime. The second example passes the output of getZonedTime to our timeNow function.

When you want to quit GHCi, use :quit.

You can use runhaskell to run the main program. Note that outputs that depend on the current time may be different when you run the program locally.