{-# LANGUAGE GeneralizedNewtypeDeriving #-} import Control.Monad.ST import Control.Monad.State import Control.Monad import Data.STRef type TheState = Int newtype M a = M { runM :: State (TheState) a } deriving (Monad, MonadState TheState) newtype N s a = N { runN :: StateT (TheState) (ST s) a } deriving (Monad, MonadState TheState) nAndStCode = do call mCode ref <- new_ref "hi" return ref new_ref :: a -> N s (STRef s a) new_ref = N . lift . newSTRef call :: M a -> N s a call (M m) = N $ do state <- get let (r, st') = runState m state put st' return r mCode :: M String mCode = do modify (+1) return "hi"