In the previous
article we discussed error-handling strategies in Haskell and derived the
Either e monad for structured error handling. In this article
we'll continue our discussion of error handling by introducing some new type
classes that will enable us to write code which recovers from errors in a
selective way (which is called exception handling in most computer
languages). Interestingly, exception handling doesn't have to be built-in in
Haskell; you get it for free once you have monads!
I also promise (threaten?) that there will be one absolutely jaw-droppingly awful pun in what follows. You have been warned.
In the previous articles in this
series, I covered the conceptual basis of monads, but the discussion was pretty
abstract. Now that (I hope) you have a pretty good idea of what monads are and
what they're for, it's time to get into the nitty-gritty details of how to
actually derive the definitions of specific monads. That means that we are
going to have to define the correct instances of the type class
Monad for the various notions of computation we talked about
previously. In our derivations, we will use our understanding of how monadic
composition should work in each particular case to give us the definition of
monadic apply (the
>>= operator), and we'll use the monad
laws to give us the definition of
It's a standing joke in the Haskell community that every Haskell programmer, as part of his or her learning process, will eventually write one or more monad tutorials. I'm certainly no exception. But since I know that there are already dozens of monad tutorials out there, some quite good, why on earth would I want to write Yet Another One? There are two reasons:
I think I can explain some aspects of monads better than most of the monad tutorials I've seen.
My own understanding of monads has improved greatly, and I'd like to try to pass that on if I can.
Ahh, summer! A time for backyard barbeques, ice cold beer, baseball games, and playing with experimental Haskell type system extensions. Or in my case, just the latter. In this article I'll show you how to compute factorials using Haskell's type system, i.e. at compile time.
Why would we want to do this? you may well ask. The real reason is "because it's neat". This is a really beautiful construction; it took my breath away when I figured it out. But another reason is that the techniques I'll illustrate are useful in many other contexts. For instance, you can use something like this to define a data type of a list which carries its length around with it (so that e.g. taking the head of an empty list is a compile-time error). This is very powerful; the more errors you can check at compile-time, the better.
Nothing in this article is even remotely original. The direct inspiration for it came from a blog post by Brent Yorgey, which I've shamelessly stolen from and extended (thanks, Brent!). The indirect inspiration was from some comments on my previous blog post on Scala, which suggested that I look at a paper on embedding object-oriented programming in Haskell. That paper, called Haskell's Overlooked Object System, by Oleg Kiselyov and Ralf Lammel, is an amazing piece of work. In order to understand it fully, though, you first have to read another paper called Strongly Typed Heterogeneous Collections, by Oleg, Ralf and Keean Schupke. So that's what I did, and in the process learned quite a bit, which I'll use to good effect below. Both of these papers are strongly recommended if you're ready for them and if you enjoy having your mind blown.
To understand this article you need to know Haskell up to and including polymorphic types and (single parameter) type classes. I'll explain everything else as we go. If you want to run the examples you'll need the GHC Haskell compiler (Hugs may also work, but I haven't tried it). I used GHC version 6.12.1 to test this code.( Read moreCollapse )