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