The problem is what you are describing. You cannot combine an existentially wrapped random seed with your initial random seed. The most obvious approach is to abandon existential quantification altogether and simply use this:
runRandomly :: RandomGen g => State ga -> g -> a runRandomly (Foo m) g = evalState mg
I do not see any problems with the most obvious approach in this context. If you really want to hide the type of seeds from the transformer, the answer of the cactus shows how to do it correctly.
In some other contexts, some similar existential wrappers can work by completing the seed with a transformer:
data Foo a where Foo :: RandomGen s => State sa -> s -> Foo a
You can see an example of something similar in the foldl package.
source share