[Haskell-beginners] making translation from imperative code

Michael Mossey mpm at alumni.caltech.edu
Tue Mar 31 08:54:12 EDT 2009


I'm translating a Python program into Haskell, and running into a 
problem---a type of code where I don't know how to make the conceptual 
shift.

The Python code does a graphical layout of a music score. There is a 
loop in which it add items (chords, symbols, text, etc.) one at a time, 
moving to the right, until it reaches the end of the line. So in typical 
imperative code, we have a bunch of loop state, such as

    - xpos of last chord or symbol placed
    - time of last chord or symbol placed
    - several StaffData objects, each containing the symbols that went
      on that particular staff
    - a cache of miscellaneous information about each symbol for later
      reference

So imperative code is pretty simple: loop, and each time update the 
state. Much of this state consists of lists  to which symbols are added 
once per loop.

I'm not sure how to conceive of this problem in Haskell. Without using 
mutable variables, I would have to "rebuild" the state on each loop. I 
can do that, but I don't want to see an ugly proliferation of variables.

I would like to encapsulate the state in a single object so I can pass 
it around as a single variable, like

LoopState = LoopState {
      lastXPos :: Int,
      lastTime :: Double,
      staffDataLists :: [ ( String, StaffData ) ],
      chunkCache :: [ ( Double, Chunk ) ]
      }

So lets say I have an instance of this call x. Let's say I want to 
create y, by "updating" lastXPos. Do I have to do something like this:

newLastXPos = 25
y = LoopState ( newLastXPos, lastTime x, staffDataLists x,
                 chunkCache x )

Obviously this is verbose compared to an imperative language in which 
one would say:
newLastPos = 25
x.setLastXPos( newLastXPos )

I am aware that Haskell provides some mutable structures, but part of 
what drew me to Haskell was the benefit of avoiding mutable data 
(reducing bugs and making it easier to reason about my program's 
behavior). Are there any shortcuts for doing things like the above?

Thanks,
Mike




More information about the Beginners mailing list