Back in November I wrote about “Mr Whitton’s timers”, a web application I wrote for three main purposes: (a) playing short sound effects and voice recordings into the classroom with minimal keypresses and no mouse usage; (b) starting timers for activities with minimal keypresses; (c) storing points scored and time wasted for the classes I teach that participate in our reward/bribery system. Over the past week I rewrote a large part of the application in Haskell. I’m learning Haskell and was looking for a beginning project to get a feel for doing basic stuff. In particular, I wanted to get a grasp of when I should be writing pure code and when I should be using a stack of monads.
My motivation was that with my old system, the scores of classes were kept in the browser’s local storage. This had the advantage that the administrative burden of the system was very low. It could be used just by putting the folder of HTML, JavaScript and CSS onto the desktop. On the other hand, it was a pain to back up the information in the system. I had to write some JavaScript that dumped the scores into a textarea, and then every school day before I went home I would copy the text from that area on the end of a text file. And further, the system could not be used outside of the English classroom, and we’re sometimes required to teach in other rooms in the school.
I managed to get the new software up to feature-completion quickly enough that I could deploy it into the classroom. However, my low-level understanding of monads a week ago caused the code to be very messy. I’m now moving lots of code around and re-organising it around a better custom monad stack. After this week of working on the project, I think that the use of a state monad stacked on top of a CGI monad stacked on top of the IO monad is very elegant, giving me just enough of the imperative paradigm that I can write reusable and short code to make my CGI application work. There’s still a great deal left to understand about monads, of course.
My appreciation for Haskell also went up a lot. The Haskell ecosystem is a mess, but the cleanliness of the monad paradigm means that this doesn’t bother me as much as it does when programming in, say, Emacs Lisp: over in that world, the ecosystem is a mess but the language is too and it can make me feel like I’m yak-shaving so much of the time.
My new software is hosted on a $5/month VPS running Debian Jessie and
Apache 2, which calls the Haskell using traditional CGI. The code is
deployed into $HOME/html
by a shell script that calls cabal build
and then copies the .cgi
script and the JavaScript and CSS assets into
place. It also creates a data
directory and chmods it to 777. This is
the old-school stuff that I did ten years ago in secondary school,
though now much better organised.
Since this project is for work I didn’t really want to be paying the upkeep on a VPS out of my own pocket, but with the state of the Haskell stack compiling even my simple little application on Windows, to host it on the computer in my office at work, was daunting. And I’m sure I will be able to find some other uses for my new webserver. It was interesting to learn just how complicated deployment has got. I’m glad I wasn’t using a full web framework like YESOD or something.