Reflection on Haskell Programming
Tags: programming.haskell
With my free time lately I’ve been tinkering on a Haskell project of
mine.
Depending on which side of the 80-20 rule you look at, I’d say I’m “about 20%
done”.
I love many things about Haskell, but, I didn’t have any proper pet projects
written in Haskell.
– The impetus to a Haskell project, I guess, is that for quick/dirty projects
Python is a much nicer choice. (Depending on your likelihood of revisiting a
project after several months/years, it may be worth considering things like
“maintainability” or “ease of refactoring”, where Haskell is a much better
choice).
Any language will have drawbacks, and Haskell certainly has some minor ones
(like weird record syntax, Cabal-Hell, etc.),
the BIG drawback to Haskell is its pure functions. – You can’t just slap a
printf
function in your function. (Concepts like laziness also mean that
tracing/debugging a function could result in different results than if you
don’t).
– The community is a bit mixed: some Haskell folk love Category Theory and
some others are amazed things compile; documentation often tends toward
academic/unhelpful. There’re many concepts to understand beyond the basics
(like Lenses, Monad Transformers (let alone monads, like the State Monad), and
potentially things like Template Haskell, Arrows, etc.).
etc. etc.
On the other hand, of Haskell they say “if it compiles, it works”.
First Half: Parsers
The script-ish part of the project parses in some file format, processes this and outputs it as CSV.
For writing parsers from scratch, Haskell (or some ML-family language) is a
good choice. I used “megaparsec”, a purported successor to the classic parsec
library. “parsec” for “Parser Combinator”.
’cause Parsec is cool, and I hadn’t had much experience writing parsers.
– The file format here is so trivial that (as is) regular expressions would do
the trick. (But then I would’ve had two problems).
In any case, I didn’t run into much trouble writing the parser.
It would’ve been better if I’d written unit-tests for the parser earlier.
In this case, the program was so quick/simple that ‘debugging’ wasn’t necessary.
Second Half: NCurses UI
Okay, so. If it’s not clear that writing this project has been an excuse for “playing with things I’ve not used before”, maybe the choice of a NCurses-base UI gives that away.
Haskell’s brick looked
interesting. It constructs/defines UI declaratively. (Loosely comparable to
Elm, minus FRP concepts).
– As with most “I’m just learning this” programming, I was able to iterate on
some of the sample programs. (During which, I learnt details of the API anyway,
so).
I’d say most of the ‘programming’ I did involved writing out types, & types of
functions in particular.
Haskell has a value called undefined
, which lets you quickly stub functions.
(It throws an error if evaluated. Scala has ???
which does the same thing. I
think these are great). – With a type signature, you roughly know whether you
can construct the output given the input; & as you implement this, what other
functions would be useful.
In order to test anything useful, this is rather bottom-up. The Python hacking
I do would be the opposite.
There was one case where code compiled, but didn’t pass its unit tests. – Though, I’d left a comment saying “To Be Implemented: (some computation)”, and this computation was what was needed for the test to pass.
– Only a few times did I ever think “I wish I could put a printf there”.
In one case, I was using unsafe pattern matching (e.g. assuming an input list
had at-least 2 elements), & this didn’t hold. (I should’ve either relaxed this
assumption, or made it so that the types I used explicitly held this
assumption). – Again, I’d left a comment somewhere critical saying “To Be
Implemented..”.
In another, my UI was receiving a new input, but not updating the UI components
to show this.
What’d I think of NCurses/Brick? Not bad. The trickiest part seems to be keeping the event-handling function to a maintainable size.
The Next 80%
Sure, I’d rather maintain a Haskell project than a Python project. But that
Haskell’s compiler is so good allows you write pretty unclear code, too.
– I’d certainly like the code to be prettier.
I’d also expect to iterate on the UI to see if it could better fit how I’d like to use it, but anyway.