I recommend this blog entry: http://twan.home.fmf.nl/blog/haskell/overloading-functional-references.details
along with a few additional combinators for imperative update: data FRef s a = FRef { frGet :: s -> a , frSet :: a -> s -> s } (=:) :: MonadState s m => FRef s a -> a -> m () ref =: a = modify $ frSet ref a fetch :: MonadState s m => FRef s a -> m a fetch ref = get >>= frGet ref Then (given the right fixity declarations which I don't remember off the top of my head) you can write code like this: attack :: Int -> Game () attack dmg = do h <- fetch (player.life) player.life =: h - dmg which works, given MonadState GameState Game, player :: FRef GameState Player, and life :: FRef Player Int. Note that (.) here is not (.) from the prelude; it's from the Ref class defined on that page. -- ryan On 4/21/08, Evan Laforge <[EMAIL PROTECTED]> wrote: > Here's some haskell to update a particular field in a data structure > (the below run in a StateT / ErrorT context): > > > set_track_width :: (UiStateMonad m) => > > Block.ViewId -> Int -> Block.Width -> m () > > set_track_width view_id tracknum width = do > > view <- get_view view_id > > track_views <- modify_at (Block.view_tracks view) tracknum $ \tview -> > > tview { Block.track_view_width = width } > > update_view view_id (view { Block.view_tracks = track_views }) > > Plus some utilities: > > > modify_at xs i f = case post of > > [] -> throw $ "can't replace index " ++ show i > > ++ " of list with length " ++ show (length xs) > > (elt:rest) -> return (pre ++ f elt : rest) > > where (pre, post) = splitAt i xs > > > update_view view_id view = modify $ \st -> st > > { state_views = Map.adjust (const view) view_id (state_views st) } > > A similar imperative update would look something like this: > > > state.get_view(view_id).tracks[tracknum].width = width > > Has there been any work on improving update syntax in haskell? > Possibly some improvement could be made with a typeclass or two and a > few custom operators, to unify some of the disparate syntax. Maybe > more improvement could be made with some TH hackery. A better record > update syntax I'm sure could improve things even more. Or maybe > there's a way to structure existing code to improve the above? > > Does anyone know of work that's been done on analysing functional > update syntax issues, and coming up with something concise and clear? > Other functional languages that do this better? It seems like an > obvious candidate for improvement. Probably not an easy one though. > There are various overlapping issues: monadic binds not mixing easily > with non-monadic functions, different data structures (maps, lists, > ...) having different update functions, record update syntax being > super wordy, and probably some other things I'm not thinking of. > > > As an aside, on the record system side, I would love to see one of the > proposed record systems implemented in GHC, whether it be trex or the > "lighter weight" version proposed by one of the Simons. Does anyone > know what the main hangup is? Unresolved issues in the proposal? No > consensus? Backward incompatibility? Not enough interested GHC devs? > All I can say is that as a heavy user of (.) I wouldn't mind > replacing them all with (#) or (@) or whatever if I got a nicer record > syntax. It wouldn't be hard to write a search/replace for (.). > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe