Given the following signature for running the monad ST
runST :: (forall s. ST s a) -> a
and the functions
I think you're missing something. The actual message GHCi gives is:
Prelude> :m +Control.Monad.ST
Prelude Control.Monad.ST> data MutVar s a = MutVar
Prelude Control.Monad.ST> :set -XRankNTypes
Prelude Control.Monad.ST> data MutVar s a = MutVar
Prelude Control.Monad.ST> let readVar = undefined :: MutVar s a -> ST s a
Prelude Control.Monad.ST> let newVar = undefined :: a -> ST s (MutVar s a)
Prelude Control.Monad.ST> runST $ readVar $ runST $ newVar True
:14:27:
Couldn't match type ‘s’ with ‘s1’
‘s’ is a rigid type variable bound by
a type expected by the context: ST s Bool at :14:1
‘s1’ is a rigid type variable bound by
a type expected by the context: ST s1 (MutVar s Bool)
at :14:19
Expected type: ST s1 (MutVar s Bool)
Actual type: ST s1 (MutVar s1 Bool)
In the second argument of ‘($)’, namely ‘newVar True’
In the second argument of ‘($)’, namely ‘runST $ newVar True’
The Haskell compiler rejects it not because of anything to do with readVar but rather because of a problem with newVar, which is that ST s (MutVar s a) allows the s to "escape" its context by jumping into the MutVar expression.