title: Writing chained mutation/modification functions for Mutable Vectors
body: <p>So I want to create a method that works the same way as</p>
  
  <pre><code>import Data.Vector as V
  import Data.Vector.Mutable as MV
  import Control.Monad.ST
  
  type DoubleVec = V.Vector Double
  
  incrAndSwap :: DoubleVec -&gt; Int -&gt; Int -&gt; Int -&gt; DoubleVec
  incrAndSwap vec i a b = runST $ do
    mvec &lt;- V.thaw vec
    oldval &lt;- MV.read mvec i                          -- 1
    MV.write mvec i (val + 1)                         -- 2
    MV.swap mvec a b
    V.freeze mvec
  </code></pre>
  
  <p>but being able to "condense" the two marked lines into one function, and be able to say:</p>
  
  <pre><code>incrAndSwap :: DoubleVec -&gt; Int -&gt; Int -&gt; Int -&gt; DoubleVec
  incrAndSwap vec i a b = runST $ do
    mvec &lt;- V.thaw vec
    incrAt mvec i
    MV.swap mvec a b
    V.freeze mvec
  </code></pre>
  
  <p>Basically, write that <code>incrAt i</code> function.</p>
  
  <p>I've tried copying the type signature of <code>MV.write</code> but I haven't been able to get anything to work with the type signatures; nothing compiles.</p>
  
  <p>Here is my most recent attempt</p>
  
  <pre><code>import Control.Monad.Primitive
  
  type MDoubleVec s = MV.STVector s Double
  
  incrAt :: (PrimMonad m) =&gt; MDoubleVec (PrimState m) -&gt; Int -&gt; m ()
  incrAt mvec i = MV.write mvec i (val + 1)
    where
      val = MV.read mvec i          -- val is stuck in monad m0
  </code></pre>
  
  <p>But I don't know how to get <code>val</code> out of the monad <code>m0</code> -- which it's in, apparently, according to the compiler.  Which makes sense.</p>
  
  <p>Does anyone know how I can do this?</p>