
Andrew Wagner wrote:
I've got several problems which seem to have a very similar structure. I want to find a way to abstract them to solve other problems which can be thought about in the same way. Here they are: http://hpaste.org/307 http://hpaste.org/308 http://hpaste.org/309
Note that these are just sketches, the programs aren't done yet. The general structure of the problem is that an object enters a system, interacts with different parts of the system, and eventually leaves, and we want to monitor some statistics about the interaction, so that we can then make some changes, and run it again, and hopefully improve it.
I like your approach. You have to watch out for the strictness bug in State/StateT for this application. Try to keep your functions polymorphic - using MonadState, as below - so it will be easy to switch between them later as needed. I would put a StdGen into the State. Generate the StdGen in your main and pass it as a parameter to your initialState function. Access it with something like getRand :: (Random a, MonadState TheState m) => a -> a -> m a getRand lo hi = do s <- get let (r, g) = randomR (lo, hi) $ randomGen s put $ s {randomGen = g} return r Then write random distribution functions that look something like theDistribution :: (MonadState TheState m) => stuff -> m [Event] theDistribution stuff = do ... r <- getRand lo hi ... You will probably want to base your random distributions on the Poisson distribution if you want your simulations to be realistic. Here are some Wikipedia links: http://en.wikipedia.org/wiki/Queuing_theory http://en.wikipedia.org/wiki/Poisson_distribution Regards, Yitz