
Hi everyone, Well, I'm trying to build a soccer server client and am using Haskell. I thought I was muddling through well enough... but I have some questions. I am using the Robot monad that I copied from Hudak's book HSOE from page 272 (assuming I would understand it later). Here's the monad code I copied: newtype Robot a = Robot (RobotState -> IO (RobotState, a)) instance Monad Robot where return a = Robot (\s -> return (s, a)) Robot sf0 >>= f = Robot (\s0 -> do (s1, a1) <- sf0 s0 let Robot sf1 = f a1 (s2, a2) <- sf1 s1 return (s2, a2)) updateState :: (RobotState -> RobotState) -> Robot () updateState u = Robot (\s -> return (u s, ())) queryState :: (RobotState -> a) -> Robot a queryState q = Robot (\s -> return (s, q s)) I defined myself a comfortable "chunk of state" (comfortable for today at least): data RobotState = RobotState { player_type :: RobotType, team_name :: String, my_current_position :: Position, visible_flags :: [ObjInfo], visible_ball :: [ObjInfo], visible_friends :: [ObjInfo], visible_foes :: [ObjInfo], audible_player_messages :: [String], my_current_mode :: RobotMode, debug_level :: [RobotDebugLevel], my_uniform_number :: Integer, game_mode :: GameMode, game_clock :: Integer } deriving Show In addition, I added some support functions similar to the ones he wrote in Section 19.3.1: assign_flags :: [ObjInfo] -> Robot () assign_flags flaglist = updateState (\s -> s {visible_flags = flaglist}) assign_friends :: [ObjInfo] -> Robot () assign_friends friendlist = updateState (\s -> s {visible_friends = friendlist}) assign_foes :: [ObjInfo] -> Robot () assign_foes foelist = updateState (\s -> s {visible_foes = foelist}) assign_ball :: [ObjInfo] -> Robot () assign_ball balllist = updateState (\s -> s {visible_ball= balllist}) Now, I read several online monad tutorials and kind of understand the notion of a thread of function calls. And I know that the do notation is syntactic sugar for the bind operation. But the code I've written is really nasty. For example, here is part of my code that handles a see record and returns a new RobotState: handleSeeRecord :: [SeeObjInfo_type] -> RobotState -> IO (RobotState, ()) handleSeeRecord seeobjlist p = do flaglist <- return (morphToList flagFinder seeobjlist) balllist <- return (morphToList ballFinder seeobjlist) friendlist <- return (morphToList friendFinder seeobjlist) foelist <- return (morphToList foeFinder seeobjlist) Robot e <- return (assign_flags (flagSpread flaglist)) Robot f <- return (assign_ball balllist) Robot g <- return (assign_friends friendlist) Robot h <- return (assign_foes foelist) (r', ()) <- e p (r'', ()) <- f r' (r''', ()) <- g r'' h r''' This actually works, but I think it can be improved with the bind operation >>= somehow. I tried a few alternatives but couldn't find one that worked. I ended up with this because it seems I had to "strip" the type off of "return (assign_flags (flagSpread flaglist))" and get the "e" that was a function. Might someone have a suggestion on how to improve this? thanks -andrew