<br><br><div class="gmail_quote">On Tue, Dec 1, 2009 at 8:01 PM, Michael P Mossey <span dir="ltr">&lt;<a href="mailto:mpm@alumni.caltech.edu">mpm@alumni.caltech.edu</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Perhaps someone could either (1) help me do what I&#39;m trying to do, or (2) show me a better way.<br>
<br>
I have a problem that is very state-ful and I keep thinking of it as OO, which is driving me crazy. Haskell is several times harder to use than Python in this instance, probably because I&#39;m doing it wrong.<br>
<br>
To give you a larger context, this problem is essentially compiling a description of music (my own) into a kind of music-machine-language (CSound). CSound is relatively untidy.<br>
<br>
In this one example, in a OO way of thinking, I have data called AssignedNumbers that assigns integers to unique strings and keeps track of the used integers and next available integer (the choice of available integer could follow a number of conventions so I wanted to hide that in an ADT.) So it has an associated function:<br>

<br>
getNumber :: String -&gt; AssignedNumbers -&gt; (Int,AssignedNumbers)<br>
<br>
What getNumber does is:<br>
<br>
  - check if the string already has a number assigned to it. If so, return that number.<br>
<br>
  - if not, pick the next available number.<br>
<br>
  - in all cases, return the possibly changed state of AssignedNumbers<br>
<br>
Then in a larger data structure, it contains fields of type AssignedNumbers. Like<br>
<br>
data MusicStuff = MusicStuff<br>
  { oscillatorNumbers :: AssignedNumbers<br>
  , tableNumbers :: AssignedNumbers<br>
  , ... }<br>
<br>
I&#39;m using MusicStuff in a State monad, so I might write a function like<br>
<br>
doSomeMusicStuff :: String -&gt; String -&gt; State MusicStuff (Int,Int)<br>
doSomeMusicStuff aString1 aString2 = do<br>
   ms &lt;- get<br>
   (o1,newOscNums) = getNumber aString1 (oscillatorNumbers ms)<br>
   (t1,newTabNums) = getNumber aString2 (tableNumbers ms)<br>
   put ms { oscillatorNumbers = newOscNums<br>
          , tableNumbers = newTabNums }<br>
   return (o1,t1)<br>
<br>
For what it does, this is extremely verbose and filled with distracting visual content. And this is just a very simple example---my real problem is several times more state-ful. Is there a better way?<br></blockquote><div>
<br>As a quick observation, you might consider changing getNumber to be something like:<br><br>nextNumber :: String -&gt; NumberGroup -&gt; State MusicStuff Int<br><br>where NumberGroup is something like <br><br>data NumberGroup = OscNums | TabNums |...<br>
<br>nextNumber updates the appropriate set of numbers in MusicStuff and returns the number. doSomeMusicStuff then becomes:<br><br>doSomeMusicStuff aString1 aString2 = (,) `liftM` nextNumber OscNums `ap` nextNumber TabNums<br>
<br>or better yet (applicatively)<br><br>doSomeMusicStuff aString1 aString2 = (,) &lt;$&gt; nextNumber OscNums &lt;*&gt; nextNumber TabNums<br>
<br> <br></div></div>