    {-# LANGUAGE BangPatterns #-}

    module Bench.Vector.Algo.MutableSet
    where

    import Prelude hiding(length, read)

    import Data.Vector.Mutable

    mutableSet :: IOVector Int -> IO Int
    {-# NOINLINE mutableSet #-}
    mutableSet :: IOVector Int -> IO Int
    mutableSet IOVector Int
    v = do
      let repetitions :: Int
    repetitions = Int
    100 -- we repeat to reduce the standard deviation in measurements.
          l :: Int
    l = IOVector Int -> Int
    forall s a. MVector s a -> Int
    length IOVector Int
    v

          -- This function is tail recursive.
          f :: Int -> Int -> IO Int
          f :: Int -> Int -> IO Int
    f Int
    i !Int
    curSum =
           if Int
    i Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0
             then
               Int -> IO Int
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Int
    curSum
             else do
               -- 'set' is what we want to benchmark.
               MVector (PrimState IO) Int -> Int -> IO ()
    forall (m :: * -> *) a.
    PrimMonad m =>
    MVector (PrimState m) a -> a -> m ()
    set IOVector Int
    MVector (PrimState IO) Int
    v Int
    i
               -- In order to make it difficult for ghc to optimize the 'set' call
               -- away, we read the value of one element and add it to a running sum
               -- which is returned by the function.
               val <- MVector (PrimState IO) Int -> Int -> IO Int
    forall (m :: * -> *) a.
    PrimMonad m =>
    MVector (PrimState m) a -> Int -> m a
    read IOVector Int
    MVector (PrimState IO) Int
    v (Int
    lInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1)
               f (i-1) (curSum+val)
      Int -> Int -> IO Int
    f Int
    repetitions Int
    0