[Haskell-beginners] A question of program style
Michael Alan Dorman
mdorman at ironicdesign.com
Tue Apr 17 19:47:57 CEST 2012
I've started writing my first non-toy program in Haskell , and things
are starting to click, at least a little bit---I find myself working
around the periphery, building functions that perform particular
operations, testing them in ghci, then figuring out how to link them up.
I at least don't feel perpetually stupid any more.
Anyway, I find myself with a couple of questions. The first, I guess,
is one of style: One Big Monad, or Several Smaller Monads?
I gather a lot of programs create a big RWST IO (or something of that
ilk) that sits at the heart of the action, and then thread that through
the whole program.
However, because I am developing in little pieces, I found myself
writing, for instance, a routine that used a WriterT IO to find all the
.info files in the directory and grab their contents and returning them
as a [(filename,contents)], which I could then parse and act upon. I'm
thinking of doing roughly the same thing for the processing of scraping
web information---creating a separate WriterT IO that goes and grabs the
content and delivers it back for parsing.
Is there a consensus that one approach is better than the other? I
guess I feel like doing it this way is really pushing me to isolate my
imperative vs. pure code, but then, it's all feeding back to processes
running in the IO monad anyway, so am I just being prissy? Are people
likely to look at my code and wonder Just What The Hell Is Going On?
The second question is one of libraries, I guess. The process I've
spec'd consists of several fairly discrete operations that have a couple
of paths through them, some of which are recursive.
For instance, if you're given a project name on the command line, you
need to hit the web site, scrape some info, get the source, unpack, walk
and parse the contents, and then generate the debian files...but if
you're called without a project name (to make updating easy), you need
to check the current dir to walk and parse the contents, figure out your
project name and version, *then* hit the website, scrape some info,
check the version numbers, perhaps get the source and unpack in which
case you need to walk and parse the contents again, then finally
generate the debian files.
When I implemented this in Perl, I actually used lazy attributes on a
central object to make most of these processing dependencies implicit
rather than explicit. It seems like this should be even easier in
Haskell, so I was wondering if there was a component out there already
that made it easy to express these sorts of dependencies to be "solved"?
I appreciate any suggestions or guidance.
1. The program is one for generating the Debian packaging files for
Drupal modules (yes, I know one already exists, I've already
re-implemented it once in Perl, so this will actually be version #3),
which is an easily explained task which nonetheless hits a lot of
capabilities (http, html parsing, untar/gz ing, reading and parsing
files, generating files from templates, etc) I would like to explore.
More information about the Beginners