[Haskell-cafe] Annotating calculations

Graham Klyne GK at ninebynine.org
Wed Jun 15 16:13:40 EDT 2005


At 18:48 15/06/05 +0200, Rene de Visser wrote:

>>From: Henning Thielemann <lemming at henning-thielemann.de>
>>On Wed, 15 Jun 2005, Rene de Visser wrote:
>> > I have a somewhat complicated calculation programmed in Haskell.
>> > This calculation is coded without using monads.
>> > I want to also produce a report describing the details of this calculation
>> > for each particular set of inputs.
>> > On the other hand replicating the calculation source code twice, once
>> > without reporting and once without seems bad.
>>
>>smaller parts. If you have more breaks you have more chances to get
>>temporary results. You can put temporary values into a data structure.
>>E.g. if you have an iteration don't write a recursion with a fixed abort
>>criterion but write a function which maps the old value to the new one,
>>then apply 'iterate' on it. Now you can inspect the temporary values and
>>you can later apply a function which decides when to stop the iteration.
>Thankyou for the reply,
>The calculation is for the mostly already structured as you have suggested.
>The trouble is there are lots of little pieces that need to be put together.
>
>Do I need to put these pieces together twice? Once to put the whole 
>calculation together?
>And once to do the reporting? This is what I'd like to avoid.
>
>(A good deal of the complexity comes from that the calculation has a 
>complex structure).
>
>It would be nice to describe the structure once (at the moment the 
>structure of the calculation is describe impliciitly in the Haskell 
>functions) and use it both for the calculation and for the reporting.

I think your "instinct" that the structure of the calculation not be 
repeated is sound.  Furthermore, I think that Haskell is well suited to 
avoiding such duplication.

Without knowing details of your problem it is difficult to be certain how 
to proceed, but it seems to me that you maybe have some kind of structure 
(or traversal pattern) over your data that can be separated from the 
computation.

A starting point might be to separate the traversal from the computation, 
and code the traversal as a higher order function (taking a parameter which 
is a function that performs the data specific operations).  If there are 
many different internal data types, it might be worth considering using a 
type class rather than a function parameter.  (Or to go the whole hog, look 
up the technique described in SPJ/Ralf Laemmel's Generic Haskell work -- 
look for "Scrap Your Boilerplate" -- but that may be more than you need.)

Staying with non-monadic functions, the computation and the formatting 
could be handled as simple functions, where formatting returns something 
like a StringS value, which can be output separately, but this might 
require some creativity for the type of the traversal function.

Another approach would be to declare your basic traversal structure type as 
an extended Functor that supports an fmapM function which allows a monadic 
function to be applied over the structure "collecting" values in some way 
-- this being used to collect or perform output.  There's a thread about 
this idea starting here:
   http://www.mail-archive.com/haskell@haskell.org/msg12757.html

Bear in mind that, with Haskell, you can design your algorithm as if it 
generates an intermediate data structure without necessarily having to 
store the entire structure in memory.  So if you have a list of values, 
each of which you require to subject to some transformation, followed by 
another operation that (say) formats the list, then you could: (a) use 
'map' to apply the transformation to each element, creating a new list, 
then (b) use something like 'concatMap show' to format and concatenate the 
values.  Doing this, it appears you need space the intermediate list, but 
lazy evaluation can mean that the entire list is never required all 
together.  In such cases, I tend to think of the intermediate list or data 
structure as describing a traversal sequence or pattern, rather than as a 
"concrete" data value.

I touch briefly on some of these issues in "Learning Haskell Notes":
   http://www.haskell.org/tmrwiki/LearningHaskellNotes#programming-idioms

#g


------------
Graham Klyne
For email:
http://www.ninebynine.org/#Contact



More information about the Haskell-Cafe mailing list