At 7:17 PM +0200 5/2/09, Nicolas Martyanoff wrote:
Content-Type: multipart/signed;
micalg=pgp-sha1;
protocol="application/pgp-signature";
boundary="ibTvN161/egqYuK8"
Content-Disposition: inline
Hi,
I don't think I already presented myself; I'm Nicolas, a 23y
french
student, trying to learn and use haskell.
I've been using C for years, for all sort of tasks, and am quite
comfortable with it. I'm also using it 40h a week in my internship
for
network systems, so I kind of know how to use it.
I discovered Haskell some monthes ago, bought `Real World
Haskell',
quickly read, and enjoyed it.
So now I'd want to use it for a small project of mine, a simple
multiplayer roguelike based on telnet. I wrote a minimal server in C,
and
it took me a few hours. Now I'm thinking about doing the same in
Haskell,
and I'm in trouble.
I don't really know how to map my ideas in haskell code. For example,
a
character can cast spells, so I'd have something like this in C:
struct hashtable spells;
struct character {
int n_spells;
struct spell **spells;
};
I thought I could do something like this in haskell:
spells = Data.Map.Map Int Spell
data Character = Character { charSpells :: [Int]
}
But now I don't know how to dynamically add new spells (new spells can
be
created in my gameplay). Since I can't assign a new value to the
`spells'
variable (Data.Map.insert returns a new map), I just don't know where
to
go.
I have the same problem for a bout every problem. I love writing
pure
functions in haskell, but as soon as I try to write some code
involving
states or side effects, I can't write a line.
I just wanted a 2d array to store a zone, for example, dead simple in
C,
but this kind of link
http://greenokapi.net/blog/2009/03/10/rough-grids-in-haskell make
me
shiver.
Point is, I'd like to use haskell, but I don't know how, it seems
totally
alien.
How did you manage to change the way you map ideas to code, from
imperative to pure functional ?
Thank you.
Regards,
--
Nicolas Martyanoff
http://codemore.org
khaelin@gmail.com
Nicolas,
First, bienvenue à Haskell ! Learning it will stretch
your mind; it may be rocky at times, but it will be rewarding.
You've quickly come upon a key difference between imperative and
functional programming. State management in Haskell is more
explicit, which is a double-edged sword. It requires greater
discipline and mechanism, but provides greater control and
security.
In your example program you could manage your state with a State
monad. Assuming you'll want to be able to do I/O, you'll
probably want to combine State with IO. For starters, something
like:
> import Control.Monad.State
> import qualified Data.Map as
M
>
> data Spell = ...
> data Character = Character { charName
:: String, charSpells :: [Spell], ... }
> data MyState = MyState { characters ::
M.Map String Character, ... }
> initialState = MyState { characters =
M.empty, ... }
>
> type MyMonad = StateT MyState
IO
>
> addSpellForCharacter :: String ->
Spell -> MyMonad ()
> addSpellForCharacter name spell =
do
> state <-
get
> let chars =
characters state
> case M.lookup
name chars of
>
Just char -> let char' = char { charSpells = spell : charSpells
char }
> state' = state { characters =
M.insert name char' chars }
>
in put state'
>
Nothing -> ... -- leave these issues for another
time
>
> main = do
>
...
> finalState
<- execStateT game initialState
>
...
>
> game :: MyMonad ()
> game = do
>
...
>
addSpellForCharacter ...
> liftIO $
putStrLn "Added spell ..."
>
...
Dean