<br><br><div class="gmail_quote">On Sat, May 2, 2009 at 6:17 PM, Nicolas Martyanoff <span dir="ltr">&lt;<a href="mailto:khaelin@gmail.com">khaelin@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hi,<br>
<br>
I don&#39;t think I already presented myself; I&#39;m Nicolas, a 23y french<br>
student, trying to learn and use haskell.<br>
<br>
I&#39;ve been using C for years, for all sort of tasks, and am quite<br>
comfortable with it. I&#39;m also using it 40h a week in my internship for<br>
network systems, so I kind of know how to use it.<br>
<br>
I discovered Haskell some monthes ago, bought `Real World Haskell&#39;,<br>
quickly read, and enjoyed it.<br>
<br>
So now I&#39;d want to use it for a small project of mine, a simple<br>
multiplayer roguelike based on telnet. I wrote a minimal server in C, and<br>
it took me a few hours. Now I&#39;m thinking about doing the same in Haskell,<br>
and I&#39;m in trouble.<br>
<br>
I don&#39;t really know how to map my ideas in haskell code. For example, a<br>
character can cast spells, so I&#39;d have something like this in C:<br>
<br>
    struct hashtable spells;<br>
<br>
    struct character {<br>
        int n_spells;<br>
        struct spell **spells;<br>
    };<br>
<br>
I thought I could do something like this in haskell:<br>
<br>
    spells = Data.Map.Map Int Spell<br>
<br>
    data Character = Character { charSpells :: [Int] }<br>
<br>
But now I don&#39;t know how to dynamically add new spells (new spells can be<br>
created in my gameplay). Since I can&#39;t assign a new value to the `spells&#39;<br>
variable (Data.Map.insert returns a new map), I just don&#39;t know where to<br>
go.</blockquote><div><br></div><div>I&#39;m not sure I understand how your C version and Haskell version are similar?<br>Wouldn&#39;t the character just have a list of Spells (since this is what the C version seems to do)? That global spells variable should probably be put in some sort of &quot;game state&quot; data type that encapsulates the game world.</div>
<div><br></div><div>Then consider writing updates as a function that takes the old value, and produces a new value. Indeed, consider letting the following function be your main &quot;update&quot; for the game state.</div>
<div><br></div><div>gameTick :: Time -&gt; PlayerInput -&gt; GameState -&gt; GameState</div><div><br></div><div>That function would update all parts of your game state, and if you want to change some property of a character, you simply compute a new character from the old one with the field you want to change updated. Because values are immutable, any data you don&#39;t touch will just refer to the old stuff so it&#39;s actually quite efficient.</div>
<div><br></div><div>You main loop could then be something like:</div><div><br></div><div>gameLoop oldTime gameState = do</div><div>  time &lt;- getTime</div><div>  let dt = time - oldTime</div><div>  input &lt;- processInput gameState </div>
<div>  gsNew &lt;- gameTick dt input gameState</div><div>  renderGame gsNew</div><div>  gameLoop time gsNew</div><div>   </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
I just wanted a 2d array to store a zone, for example, dead simple in C,<br>
but this kind of link<br>
<a href="http://greenokapi.net/blog/2009/03/10/rough-grids-in-haskell" target="_blank">http://greenokapi.net/blog/2009/03/10/rough-grids-in-haskell</a> make me<br>
shiver.</blockquote><div><br></div><div>Try a list of lists, or better yet just an Array. Make sure you update the grid &quot;in bulk&quot; though, as modifying just a single element at a time is slow with immutable arrays.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
Point is, I&#39;d like to use haskell, but I don&#39;t know how, it seems totally<br>
alien.<br>
<br>
How did you manage to change the way you map ideas to code, from<br>
imperative to pure functional ?</blockquote><div><br></div><div>Massive brain-rewiring. Keep at it, don&#39;t think in terms of modifying state, think of it as computing new values from old values. I find that the payoff of learning to think ,like this is massive, as it&#39;s usually much easier to reason about.</div>
</div><div><br></div><div>If you really do lots of &quot;state&quot; in a program, consider using a state monad like someone else already mentioned, but honestly I&#39;d try to stay away from it and stick to a more &quot;functional&quot; style as far as possible.</div>
<br>-- <br>Sebastian Sylvan<br>+44(0)7857-300802<br>UIN: 44640862<br>