Unwrapping the STT monad in a transformer stack?
<p>This question is apparently related to the problem discussed <a href="https://stackoverflow.com/questions/32654814/trouble-with-sts-type-in-a-transformer-stack">here</a> and <a href="https://stackoverflow.com/questions/9468963/runst-and-function-composition">here</a>.  Unfortunately, my requirement is slightly different to those questions, and the answers given don't apply to me.  I also don't really understand <em>why</em> <code>runST</code> fails to type check in these cases, which doesn't help.</p>

<p>My problem is this, I have one section of code that uses one monad stack, or rather a single monad:</p>

<pre><code>import Control.Monad.Except
type KErr a = Except KindError a
</code></pre>

<p>Another section of code needs to integrate with this that wraps this within the <a href="https://hackage.haskell.org/package/STMonadTrans-0.3.3/docs/Control-Monad-ST-Trans.html" rel="nofollow noreferrer">STT monad</a>:</p>

<pre><code>type RunM s a = STT s (Except KindError) a
</code></pre>

<p>At the interface between these sections, I clearly need to wrap and unwrap the outer layer.  I've got the following function to work in the <code>KErr</code> -> <code>RunM</code> direction:</p>

<pre><code>kerrToRun :: KErr a -&gt; RunM s a
kerrToRun e = either throwError return $ runExcept e
</code></pre>

<p>but for some reason I just can't get the converse to type check:</p>

<pre><code>runToKErr :: RunM s a -&gt; KErr a
runToKErr r = runST r
</code></pre>

<p>I'm working on the assumption that as the <code>RunM</code>'s inner monad has the same structure as <code>KErr</code>, I can just return it once I've unwrapped the <code>STT</code> layer, but I don't seem to be able to get that far, as <code>runST</code> complains about its type arguments:</p>

<pre><code>src/KindLang/Runtime/Eval.hs:18:21:
    Couldn't match type ‘s’ with ‘s1’
      ‘s’ is a rigid type variable bound by
          the type signature for runToKErr :: RunM s a -&gt; KErr a
          at src/KindLang/Runtime/Eval.hs:17:14
      ‘s1’ is a rigid type variable bound by
           a type expected by the context:
             STT s1 (ExceptT KindError Data.Functor.Identity.Identity) a
           at src/KindLang/Runtime/Eval.hs:18:15
    Expected type: STT
                     s1 (ExceptT KindError Data.Functor.Identity.Identity) a
      Actual type: RunM s a
</code></pre>

<p>I've also tried:</p>

<pre><code>runToKErr r = either throwError return $ runExcept $ runST r
</code></pre>

<p>in order to more strongly isolate <code>runST</code> from its expected return type, in case that was the cause of the issue, but the results are the same.</p>

<p>Where is this <code>s1</code> type coming from, and how do I persuade ghc that it's the same type as <code>s</code>?</p>