module Indexation.Vector
where
import Indexation.Prelude
import Data.Vector
import qualified Data.Vector.Mutable as A
import qualified Data.HashMap.Strict as B
import qualified DeferredFolds.UnfoldM as UnfoldM
{-# NOINLINE populate #-}
populate :: Monad effect => Int -> effect (Int, element) -> effect (Vector element)
populate size effect =
do
mv <- return (unsafeDupablePerformIO (A.unsafeNew size))
let
loop stepsRemaining =
if stepsRemaining > 0
then do
(index, element) <- effect
() <- return (unsafeDupablePerformIO (A.write mv index element))
loop (pred stepsRemaining)
else do
!v <- return (unsafeDupablePerformIO (freeze mv))
return v
in loop size
{-# INLINE indexHashMapWithSize #-}
indexHashMapWithSize :: Int -> HashMap element Int -> Vector element
indexHashMapWithSize size hashMap =
unsafePerformIO $ do
mv <- A.unsafeNew size
let
step () element index = unsafeDupablePerformIO (A.write mv index element)
!() = B.foldlWithKey' step () hashMap
in freeze mv
{-# NOINLINE unfoldM #-}
unfoldM :: Monad m => Int -> UnfoldM m (Int, element) -> m (Vector element)
unfoldM size unfoldM =
let
step mv (index, element) = return (unsafeDupablePerformIO (A.write mv index element $> mv))
in do
!mv <- return (unsafeDupablePerformIO (A.unsafeNew size))
UnfoldM.foldlM' step mv unfoldM
!iv <- return (unsafeDupablePerformIO (unsafeFreeze mv))
return iv