<br>For working with record fields inside of state monads I would recommend trying out one of these packages:<br>lenses<br>fclabels<br>data-accessor<br>
(I think I&#39;m forgetting a couple)<br><br>They all have special mechanisms for working with record fields inside state monads (and have lots of other cool stuff)<br>I&#39;m partial to lenses (I wrote it :) ), but the others are quite good as well.<br>
<br>Hmmm I just noticed that hackage is not generating the documentation for latest version of lenses. I shall have to find out why.<br>In the meantime, the documentation for the 0.1.2 version is essentially the same.<br>
<br>- Job<br><br><br><div class="gmail_quote">On Thu, Jul 8, 2010 at 4:08 AM, Michael 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;">
I&#39;m fairly beginnerish to Haskell, and come from OO. I have a complaint about Haskell, but I think I found a good solution. Any suggestions welcome.<br>
<br>
I have RSI and like to minimize typing. The use of classes as name spaces helps to do that. Also I can use some Emacs abbreviation magic easily with OO and not so easily with Haskell. I&#39;ll explain in a second.<br>
<br>
In Haskell, when defining data for complex programs I like to use named fields to allow for changing data definitions without having to change all code. But named fields are top-level functions (I think). They must be chosen not to clash.<br>

<br>
My habit has been to prefix them with the name of the constructor. So in a program for playing back musical documents that needs to track some state, we have:<br>
<br>
data PlayState = PlayState<br>
                 { playState_cursor :: Int<br>
                 , playState_verts :: [Loc]<br>
                 , playState_len :: Int<br>
                 , playState_doc :: MusDoc<br>
                 }<br>
<br>
Note all these &quot;playState_&quot; prefixes. Lots of typing, which is not good.<br>
<br>
In OO, you could type<br>
<br>
   x.cursor()<br>
<br>
In Haskell you have to type<br>
<br>
   playState_cursor x<br>
<br>
which also, I feel, is harder to read.<br>
<br>
Now suppose I want to use PlayState with a State monad.<br>
<br>
-- Increment the cursor.<br>
incrCursor :: State PlayState ()<br>
incrCursor =<br>
  cur &lt;- gets playState_cursor<br>
  len &lt;- gets playState_len<br>
  let newCur = min (cur+1) (len-1)<br>
  p &lt;- get<br>
  put $ p {playState_cursor = newCur}<br>
<br>
Okay, I&#39;m sorry, that is just a lot of typing for what it is doing. Not good for people with RSI, and not all that readable.<br>
<br>
I could define a function to make modifying the state a little easier.<br>
<br>
playState_update_cursor :: Int -&gt; PlayState -&gt; PlayState<br>
playState_update_cursor i p = p {playState_cur=i}<br>
<br>
Then incrCursor would look like:<br>
<br>
incrCursor :: State PlayState ()<br>
incrCursor =<br>
  cur &lt;- gets playState_cursor<br>
  len &lt;- gets playState_len<br>
  let newCur = min (cur+1) (len-1)<br>
  modify (playState_update_cursor newCur)<br>
<br>
Notice how often the characters &quot;playState_&quot; get typed. This would be a great situation for Emacs abbreviations. When you define an abbreviation in Emacs, such as defining &quot;xps&quot; to expand to &quot;PlayState&quot;, emacs will watch for the characters xps. It will then replace &quot;xps&quot; with &quot;PlayState&quot; when you type a non-alphanumeric character following &quot;xps&quot;. So if I type &quot;xps.&quot; the moment I hit &quot;.&quot; it changes to &quot;PlayState.&quot;<br>

<br>
But I would have a hard time using this feature with &quot;playState_&quot; because it is always followed by an alphanumeric character.<br>
<br>
So my idea, now, is to put the definition of PlayState in its own module and import it qualified as PlayState.<br>
<br>
---------------- module PlayState --------------<br>
<br>
data PlayState = PlayState<br>
   { cursor :: Int<br>
   , verts :: [Loc]<br>
   , len :: [Int]<br>
   , doc :: MusDoc<br>
   }<br>
<br>
update_cursor i p = p {cursor = i}<br>
<br>
-----------------------------------------------<br>
<br>
I got rid of the &quot;playState_&quot; prefixes because I am not worried about using generic field names like &quot;doc&quot;. They won&#39;t clash if I always import this qualified. And that reduces the necessary typing in the definition.<br>

<br>
Now my monad looks like<br>
<br>
testMonad = do<br>
  cursor &lt;- gets PlayState.cursor<br>
  len    &lt;- gets PlayState.len<br>
  let newCur = min (cur+1) (len-1)<br>
  modify $ PlayState.update_cursor newCur<br>
<br>
Now I can define an abbreviation for PlayState. This is a big help. Also, I find this more readable. To me<br>
<br>
   PlayState.cursor<br>
<br>
is more readable than<br>
   playState_cursor<br>
<br>
For one thing, syntax highlighting helps in the former case. For another, the latter case requires that you recognize a naming convention, but the former case says clearly: &quot;cursor is within the namespace PlayState, so this combination must be describing a cursor related to PlayState.&quot;<br>

<br>
<br>
<br>
<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</blockquote></div><br>