
Hi Timotej, I must admit I haven't fully analyzed the problem, but this type of question intuitively sounds like a job for… *drumroll* Type Families! (or his sidekick, functional dependencies)
newtype ST2 r w s a = ST2 { unwrapST2 :: ST s a } deriving (Functor)
But as you can see, now all my types got tainted by s even though sharing the same r or w implies sharing the same s. Is there a way how to hide s from the type signatures, but still preserve an ability to write runST2 without resorting to IO/RealWorld? I have tried writing such a function and failed.
As I said, I have almost no idea what I'm doing, but maybe you could get somewhere along the lines of type family StateSupporting reading writing :: * newtype ST2 r w a = ST2 { unwrapST2 :: ST (StateSupporting r w) a } ? Cheers, MarLinn