[Haskell-cafe] Haskell-Cafe Digest, Vol 93, Issue 58

Gregory Guthrie guthrie at mum.edu
Thu Jun 9 05:17:39 CEST 2011

An earlier note on students reactions to the imperative style forced on them by some Haskell libraries ("do ...") is interesting, and seems similar to an observation in a project I was developing for students; making a version of a simple lab from previous SML assignment.

It uses a dictionary to do some statistics for a text analysis, but since the dictionary is read at a leaf node of the analysis algorithm, that function must be IO(), and thus the analysis using it also, ... etc. all the way up to the top.

So the implication of the rules:
  1) all IO must start from the top level, and there is only one IO
  2) you cannot extract anything from an IO

Seems to be that the whole program structure becomes a series of do... blocks, which is basically a sequential imperative looking style.
The general advice of "Strive to keep as much of the program pure as possible" thus seems difficult.

An option I suppose would be to read the dictionary at the top level, and then pass it all the way down to the analysis routine that uses it, but that exposes the details of how the analysis is done, and couples the top and bottom levels of the previously modular functions.

While this is all logical and understandable, it is quite different than how I did this in SML; where I could encapsulate the IO in the analysis function. It was a local secret of the analysis what data it needed, and where it came from. Note that (of course...) if the dictionary was static and an internal data structure, then this would all go away. It is interesting to me (and curious at first) that one could not somehow treat a "constant" data definition file resource in a more encapsulated manner, and not have it ripple all the way up through the program because it was "impure" once converted to an external definition (=IO). My first impulse was to read the dictionary in a do... and then try to extract it and go merrily on, but that won't work - by design of course!

Considering something like a properties file in Java, it thus seems like every part of a program wanting to use these, must either be passed some global definition, or become a leaf on a hierarchy of do.. blocks if it does its own IO to read the properties.

Anyway, while the more precise treatment and isolation of IO in Haskell seems valuable, it also seems to have a notable impact on the lack of ability to encapsulate and decouple parts of the program, and keep things pure between them. I suppose this is because that by definition, once you have touched IO at any leaf of a program, the whole thing is impure all the way up the functional tree.

I rather had the feeling expressed by Robert Harper:
  " Once you're in the IO monad, you're stuck there forever, and are reduced to Algol-style imperative programming."

Just an observation, in case I am missing something - being fairly new to Haskell.  I suppose this is just an adjustment to proper treatment of the impurity of IO, but the effect on program structure was not good.  :-)
> -----Original Message-----
> Subject: Haskell-Cafe Digest, Vol 93, Issue 58
> Now, I have a  personal pedagogical comment.
>A few months ago I gave to some 30 students an
>The results? A true DISASTER!
> The OpenGL bindings in Haskell are hardly "functional".
> You make us sweat with generic functional patterns, laziness, exquisite typing, non-determinism monad, parsing tools, etc.,
>  and then you throw us into this ugly imperativism !

More information about the Haskell-Cafe mailing list