Stack usage with a state monad
Graham Klyne
gk at ninebynine.org
Fri Jan 2 14:46:04 EST 2004
At 15:37 31/12/03 +0000, Joe Thornber wrote:
>On Wed, Dec 31, 2003 at 02:38:06PM +0000, Graham Klyne wrote:
> > getOrCachePositionValue pos =
> > do { mcache <- gets (findPos pos) -- Query cache for position
> > ; case mcache of
> > Just cached -> return (cachedVal cached) -- Return cached value
> > Nothing -> -- Not in cache:
> > do { let val = calculatePosVal pos -- Calculate new value
> > ; modify (addToCache pos val) -- Cache new value
> > ; return val -- Return new value
> > }
> > }
> >
> > (This code of off-the-cuff, and may contain errors)
> >
> > My point is that the function 'calculatePosVal' used here to evaluate a
> > position not in the cache simply returns the calculated value, not a
> > monad. This function is wrapped in "high level" code that queries and/or
> > updates the cache which is kept in a state monad. Thus, the return
> type of
> > 'getOrCachePositionValue' would be a monad of the appropriate type.
>
>But I want calculatePosVal to use the cache too :(
Well, maybe you really do need to run your calculation in the state monad,
but I'll ask one more question: to you need your 'calculatePosVal' to
*use* the cache, or to *update* it? If you simply need access to the
cache, then the function could accept cache data extracted from the state
monad as an additional argument; e.g.
getOrCachePositionValue pos =
do { cacheState <- get -- Get current cache state
; let mcache = findPos pos cacheState -- Query cache for position
; case mcache of
Just cached -> return (cachedVal cached) -- Return cached value
Nothing -> -- Not in cache:
do { let val = calculatePosVal pos cacheState
-- Calculate new value
; modify (addToCache pos val) -- Cache new value
; return val -- Return new value
}
}
If your calculation really needs to update the cache state as it goes
along, then I agree that it needs to be run in the state monad. But even
then, I'd be inclined to look for sub-calculations that can be evaluated as
ordinary functions.
Anyway, I think I've probably added enough noise to this debate. Whatever
approach you may use, have fun!
#g
------------
Graham Klyne
For email:
http://www.ninebynine.org/#Contact
More information about the Haskell-Cafe
mailing list