The size of the code is roughly the same as the size in Ruby, but I think a few of the constructs are pretty clean in Haskell.
I ended up defining a type class (Combinable) for this which I’m sure is already implemented somewhere in the Haskell world in some form, but I couldn’t find it. I’d be particularly interested in knowing if there’s a Category for things that can be reduced by combining some of the elements in some way; I’ve had to solve that problem a few times now.
It definitely seems close to Monoid/MonadPlus, but there isn’t really a zero case - how would I define mempty or mzero?
I originally implemented this using Parsec. It ended up being more verbose, because I couldn’t find a good way to have it parse patterns like F12/05/20’ and return them as a single string. Because of that, I had to part out the individual parts, let bindings, and then recombine them again. Maybe there’s a better way to use Parsec? If so, that would be nice, because Parsec handles the “Error on 1: whatever” logic for you (which I implemented in LineParser).