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