Reflection on Haskell Programming

Posted on June 8, 2016 by Richard Goulter
Tags:

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.


Newer post Older post