Yitzchak Gale gale at sefer.org
Mon Feb 5 09:17:18 EST 2007

```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.

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
```