
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