While learning and experimenting the use of Data.Vector.Unboxed.Mutable
with runST
came up with this code:
{-# LANGUAGE BangPatterns #-}
import qualified Data.Vector.Unboxed.Mutable as UVM (unsafeNew, unsafeWrite, unsafeRead)
import Control.Monad.ST
test :: Int -> Int
test len = runST $ do
vec <- UVM.unsafeNew (len - 1)
let
fill !i
| i >= len = sumVec 0 0
| otherwise = do
UVM.unsafeWrite vec i i
fill (i + 1)
sumVec !k !total
| k >= len = return total
| otherwise = do
x <- UVM.unsafeRead vec k
sumVec (k + 1) (total + x)
fill 0
testParent = test 5
If I run this, Haskell stops working. I came to this while trying to make this work:
test :: Int -> Int
test len = do
.
.
.
testParent = runST $ test 5
But with no success.
test
function using runST
but outside of test
? Was reading at this but still not clear why it doesn't works.In this line:
vec <- UVM.unsafeNew (len - 1)
you are creating a vector of length len-1
. But you are writing into indices 0 through len-1
so you need a vector of length len
.
Change that to len
and it will work.
As to your second question, you can use runST
like this:
-- test now begins with the `do` statement
test len = do
vec <- UVM.unsafeNew len
...
main = print $ runST $ test 5
main now has to wrap the call to test in runST
.