
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]})