Indexing Haskell (book)

Tags: Haskell, personal

I’ve spent the past few weeks trying very hard to get Haskell Programming from First Principles finished up. There were errors to correct, LaTeX tags to standardize, proofreading to do, and an index to make. Indexing turned out to be more interesting and rewarding than I’d thought it would be.

Previously, this book did not have much of an index which was sort of OK because it was only an ebook, and you can search the PDF. We had sprinkled a few index tags about, but not many. It was clear that for the print version, I’d have to add a whole bunch of index tags by hand1, and I planned to do that as I proofread the book. I’m reading it anyway, it should be simple to just put in index tags as necessary, right?

The first problem was that you need a different focus (literally) when you proofread as opposed to when you edit content, and placing index tags is closer to content editing: I had to keep asking myself, we mention this thing in this paragraph, but is this a good place for an index tag for that thing? How essential is this particular information? Is it merely a mention or something substantive? If I were looking up this term in the book, is this likely to be an explanation or example I was looking for?

I also found, though, that indexing that way wasn’t giving me a high-level view of the index and its role in the book. While I have always appreciated a great book index, to the extent that I often wish even fiction were indexed (remember that passage where…? how can I find that again?), I did not know how to make a great index happen.

The Role of the Index

I started thinking about what makes a bad index. So many books have unhelpful ones. In one of my favorite cookbooks, the recipes are mostly indexed by the name the authors gave them, so to look up how to make that soup we like, I have to remember whatever they called it, not just “zucchini soup,” and unfortunately I never can (I used colored pencils to highlight my favorite recipes in the index, but I shouldn’t have had to). Other books seem to point you to just any use of a given term, not necessarily the ones that contain something essential about it. For this book, I don’t want to index literally every mention of the Bool or Maybe type, for example, only the important ones.

I started to think about the role the index plays in the book’s user interface. A book’s UI includes more than the index, of course. The design and layout of the book as a whole are also part of it, a part we’d invested a great deal of effort into. The table of contents, perhaps along with a “how to use this book” section, is also part of the user interface, but that is the authors telling you how they want you to use the book. The index, on the other hand, is there to let the reader use the book how they want to use it.

How would someone who has read the whole book but wants to refer back to something use the index? How would a reader who has just picked it up and maybe only read a chapter or two use it? What kinds of information would people want to know about the book that the index could reveal even if they hadn’t read any of it?

Placing index tags as I went through the book proofreading did a pretty good job at getting important instances of important terms listed in the index – although when I went back to earlier chapters after I’d finished the last chapters, I realized I hadn’t been nearly thorough enough early on. Getting those cross-listed so they are accessible through various terms (e.g., “sectioning” is listed as both “sectioning” and under “infix operators, sectioning”) was the next step. You do not want to force your readers to remember the name of the zucchini soup.

But the more I thought about the index as part of the book’s UI, the less satisfied I was with what I’d done so far. I wondered what other assistance the index could supply, what other lenses into the book, and the language, it could provide.

Helpful lists, I hope

Because of the way the book is laid out, intended to be worked through mostly sequentially, we don’t have a specific place where we cover all the GHCi commands, or all the Stack and Cabal stuff you need to know. That kind of information is sprinkled throughout the book, wherever it came up in the course of teaching Haskell. Making sure those were grouped into lists in the index seemed a good next step.

But why stop there?

We’d made a point to explain GHCi error messages at various points in the book. They can be intimidating and hard to interpret, but they also give useful feedback, so we want to help people see them as part of a dialogue with the compiler. It seemed appropriate, then, to index some of those. If you get an “actual type did not match expected type” message and don’t know or can’t remember which is which, that’s indexed, and the index points at places where we explain what that message is telling you. Wondering why you get a “No instance for Show” when you apply a function to too few arguments – that answer is now easy to find!

Next, I made an entry for “language extension” and cross-listed the ones we cover. Again, coverage of those (not by any means all of the language extensions that exist) is sprinkled throughout the book, but any reader might be in a position where they want to see TypeApplications or InstanceSigs demonstrated, before they reach a point where we do that (I think we probably should encourage more Haskell learners to use those liberally) – or maybe they’ve already started a project that needs OverloadedStrings, as so many projects do, and need a quick way to find explanations and examples of usage. Each language extension we cover is listed both under its own name as well as in the list of language extensions.

It was in the course of doing this that I learned the difference between pragma and language extension so then I also made a list of the pragmas we give at least some coverage, too. Probably not as useful to know as the extensions, but it can’t hurt, right? I, for one, had forgotten we talked about INLINABLE.

Some internet argument about the fact that Haskell is made up of expressions and declarations not just functions made me want to list the varieties of declaration. We do talk about what the difference is in the book but what if you just want to know what all constitutes a declaration? The Haskell Report tells you, of course, but we could offer help, too. Our list isn’t as comprehensive as the Report’s because, again, it only covers what we discussed in the book.

For similar reasons, I decided to do the same thing with keywords – what are the keywords in Haskell and what are they used for? Again, my list doesn’t include all of them, only what we covered in the book.

At the last minute, I decided to use “library” as an index term. There are a few libraries we really delved into – we used the testing libraries QuickCheck, hspec, and checkers a lot. The data structures chapter has solid introductions to criterion, containers, and vector. Those and bytestring and text might seem reasonably obvious to cover. But I think it’s less obvious that we covered scotty, network, random, trifecta, aeson, and sqlite-simple – at least three of those are used in complete projects, even.2

So, now, when you’re ready to start a project, no matter where you are in the book, and you want direct help using random or wreq or time, you can find it.

The library index term does not include every library we mention in the book, by the way, only the ones where I considered the example or explanation substantial enough to bother. I may reconsider what I included there for subsequent editions of the book. It may be worthwhile including every library we mention to help people figure out which Haskell libraries are commonly used for things like streaming (not covered in the book, but mentioned).

I am pleased with my work here. I hope that the index will serve as a good entry point and reference to – well, not just the book, but to Haskell, or GHC Haskell, at least the parts that seemed most relevant to going from unfamiliarity with the language to building projects with it.

1 LaTeX generates the index, but you still have to place the tags telling it to index something.

2 We have a perhaps TMI investigation of scotty’s transformer stacks in the monad transformers chapter, but not a full web app built with it.

If you like my writing, consider buying me coffee or check out Type Classes, where I teach and write about Haskell and Nix.