Search code examples
haskellstate-monad

Haskell crashes with runST and Data.Vector.Unboxed.Mutable


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.

  • Why does Haskell (7.8.3) crashes with the provided code?
  • How can I compute the test function using runST but outside of test? Was reading at this but still not clear why it doesn't works.

Solution

  • 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.