[Haskell-cafe] State separation/combination pattern question

Reto Kramer ml at retokramer.net
Fri Dec 22 01:11:22 EST 2006


I'm looking for a pattern to use for "state separation" in my  
application.

I need to write two "stateful libraries". One is a partitioned in- 
memory store, the other a disk based store with an in-memory cache  
fronting it. Both store modules need the IO and State monad.

My aim is to write the libraries independently from one another in  
such a way that they are not aware of the context they will be used  
in. Both stores are called from a breadth first search loop.

The example below extracts the essence of my current approach. foo is  
function in one of the store modules, bar is from the other type of  
store. Both manipulate their type of state (StateA, StateB).  They  
extract their slice of the "global" application level state  
(AppStateRec). What I don't like is that the code in foo and bar know  
about the AppStateRec and that they need to get the "a", or "b" slot  
respectively. The store modules should not have such coupling with  
their client code.

I've tried to thread the two states (StateA and StateB) using a chain  
of StateT ... StateT ..., but couldn't really make that work. It  
seems rather arbitrary in this case which state to make the inner/ 
outer one and depending on this ordering the "lifts" have to go with  
one or the other set of store calls.

What I'm really looking for is not so much the chaining of StateT  
compositions, but rather the isolation of StateA from StateB while  
they both flow from the search loop into the respective library calls  
(foo, bar) transparently to the application programmer.  I'm hoping  
there's a way to have the loop be in a State monad whose content is  
the sum of the two states that are needed for the foo and bar call  
made to the stores from inside the loop. The calls sites for foo and  
bar should then extract the right component of the global state and  
thread only that state through into the modules. Sounds like magic,  
but how close can I get?

I've been unable to find a pattern on the WIKI or the web that refers  
to this type of "state composition" (or I may not have recognized the  
match).  I trust many of you have run into this and there's an  
obvious and straight forward best way to address this type of state  
handling.

Thanks,
- Reto

--------------------------
-- ghci -fglasgow-exts ...
--
type StateA = [Integer]
type StateB = [Integer]

data AppStateRec = AppStateRec { a :: StateA, b :: StateB } deriving  
Show

foo :: MonadState AppStateRec m => m ()
foo = do st <- get
	 put $ st { a = 1:(a st) }

bar :: MonadState AppStateRec m => m ()
bar = do st <- get
	 put $ st { b = 2:(b st) }

type Eval a = StateT AppStateRec Identity a

exec :: Eval ()
exec = do foo
	  bar
	  foo
	  foo
	  bar

go = runIdentity $ runStateT exec AppStateRec { a = [], b = [] }

Prints: ((),AppStateRec {a = [1,1,1], b = [2,2]})


More information about the Haskell-Cafe mailing list