diff --git a/indexation.cabal b/indexation.cabal
--- a/indexation.cabal
+++ b/indexation.cabal
@@ -1,5 +1,5 @@
 name: indexation
-version: 0.4.9
+version: 0.5
 category: Data
 synopsis: Tools for entity indexation
 description: A set of tools for indexing entities
@@ -20,10 +20,7 @@
   exposed-modules:
     Indexation.Data
     Indexation.IO
-    Indexation.Predicate
-    Indexation.Potoki.Produce
     Indexation.Potoki.Transform
-    Indexation.FoldM.Index
   other-modules:
     Indexation.Cereal.Get
     Indexation.Cereal.Put
@@ -32,30 +29,20 @@
     Indexation.Instances.Cereal
     Indexation.Prelude
     Indexation.Types
-    Indexation.Functions
-    Indexation.FoldM.Basic
-    Indexation.Utils.Vector
-    Indexation.Utils.BitVector
-    Indexation.Utils.Unfoldr
+    Indexation.Vector
   build-depends:
-    base >=4.11 && <5,
-    bitvec >=0.1.0.2 && <0.2,
+    base >=4.7 && <5,
     bytestring >=0.10.8 && <0.11,
     cereal >=0.5.5 && <0.6,
-    cereal-vector >=0.2.0.1 && <0.3,
-    contravariant >=1.4 && <2,
-    deferred-folds >=0.9 && <0.10,
+    deferred-folds >=0.6 && <0.7,
     focus >=1.0.1 && <1.1,
-    foldl >=1 && <2,
     hashable >=1 && <2,
-    list-t >=1 && <1.1,
+    hashtables >=1.2.3.1 && <1.3,
     mmorph >=1 && <2,
-    potoki >=2.0.15 && <2.1,
+    potoki >=2 && <2.1,
     potoki-cereal >=0.3 && <0.4,
     profunctors >=5.2 && <6,
-    stm-containers >=1.1 && <1.2,
     text >=1 && <2,
     transformers >=0.5 && <0.6,
     unordered-containers >=0.2.9 && <0.3,
-    vector >=0.12 && <0.13,
-    vector-algorithms >=0.7.0.4 && <0.8
+    vector >=0.12 && <0.13
diff --git a/library/Indexation/Cereal/Get.hs b/library/Indexation/Cereal/Get.hs
--- a/library/Indexation/Cereal/Get.hs
+++ b/library/Indexation/Cereal/Get.hs
@@ -5,7 +5,7 @@
 import Indexation.Types
 import Data.Serialize.Get
 import qualified Data.HashMap.Strict as A
-import qualified Data.Vector.Generic as B
+import qualified Data.Vector as B
 
 
 getIndexHashMap :: (Eq k, Hashable k) => Get k -> Get (HashMap k Int)
@@ -33,8 +33,7 @@
           entity <- getEntity
           return (A.insert entity index hashMap)
 
-{-# INLINE getVector #-}
-getVector :: B.Vector vector element => Get element -> Get (vector element)
+getVector :: Get element -> Get (Vector element)
 getVector getElement =
   getSize >>= getElements
   where
diff --git a/library/Indexation/Cereal/Put.hs b/library/Indexation/Cereal/Put.hs
--- a/library/Indexation/Cereal/Put.hs
+++ b/library/Indexation/Cereal/Put.hs
@@ -4,16 +4,15 @@
 import Indexation.Prelude
 import Indexation.Types
 import Data.Serialize.Put
-import qualified Data.Vector.Generic as B
+import qualified Data.Vector as B
 
 
-{-# INLINE putVector #-}
-putVector :: (B.Vector vector element) => Putter element -> Putter (vector element)
+putVector :: Putter element -> Putter (Vector element)
 putVector putElement vector =
   putSize *> putElements
   where
     putSize = putInt64le (fromIntegral (B.length vector))
-    putElements = B.foldM'_ (const putElement) () vector
+    putElements = traverse_ putElement vector
 
 putEntityTable :: Putter entity -> Putter (EntityTable entity)
 putEntityTable putEntity (EntityTable vector) =
diff --git a/library/Indexation/Constructors/EntityTable.hs b/library/Indexation/Constructors/EntityTable.hs
--- a/library/Indexation/Constructors/EntityTable.hs
+++ b/library/Indexation/Constructors/EntityTable.hs
@@ -3,7 +3,7 @@
 
 import Indexation.Prelude hiding (lookup)
 import Indexation.Types
-import qualified Indexation.Utils.Vector as A
+import qualified Indexation.Vector as A
 
 
 indexTable :: IndexTable entity -> EntityTable entity
diff --git a/library/Indexation/Data.hs b/library/Indexation/Data.hs
--- a/library/Indexation/Data.hs
+++ b/library/Indexation/Data.hs
@@ -1,9 +1,25 @@
 module Indexation.Data
 (
-  module Exports,
+  Index(..),
+  EntityTable,
+  IndexTable,
+  Indexer,
+  lookupEntity,
+  lookupIndex,
 )
 where
 
-import Indexation.Types as Exports (Index(..), EntityTable, IndexTable, Indexer, IndexSet, IndexCounts)
+import Indexation.Prelude
+import Indexation.Types
 import Indexation.Instances ()
-import Indexation.Functions as Exports
+import qualified Data.Vector as Vector
+import qualified Data.HashMap.Strict as HashMap
+
+
+lookupEntity :: Index entity -> EntityTable entity -> Maybe entity
+lookupEntity (Index indexPrim) (EntityTable vector) =
+  vector Vector.!? indexPrim
+
+lookupIndex :: (Eq entity, Hashable entity) => entity -> IndexTable entity -> Maybe (Index entity)
+lookupIndex entity (IndexTable _ hashMap) =
+  fmap Index (HashMap.lookup entity hashMap)
diff --git a/library/Indexation/FoldM/Basic.hs b/library/Indexation/FoldM/Basic.hs
deleted file mode 100644
--- a/library/Indexation/FoldM/Basic.hs
+++ /dev/null
@@ -1,14 +0,0 @@
-module Indexation.FoldM.Basic
-where
-
-import Indexation.Prelude
-import Control.Foldl
-import qualified Data.Vector.Unboxed as UnboxedVector
-import qualified Data.Vector.Unboxed.Mutable as MutableUnboxedVector
-
-
-countIndices :: Int -> FoldM IO Int (UnboxedVector.Vector Word32)
-countIndices amount = FoldM step init extract where
-  init = MutableUnboxedVector.new amount
-  step mv index = MutableUnboxedVector.modify mv succ index $> mv
-  extract = UnboxedVector.unsafeFreeze
diff --git a/library/Indexation/FoldM/Index.hs b/library/Indexation/FoldM/Index.hs
deleted file mode 100644
--- a/library/Indexation/FoldM/Index.hs
+++ /dev/null
@@ -1,12 +0,0 @@
-module Indexation.FoldM.Index
-where
-
-import Indexation.Prelude
-import Indexation.Types
-import Indexation.Data
-import Control.Foldl
-import qualified Indexation.FoldM.Basic as Basic
-
-
-indexCounts :: Int -> FoldM IO (Index a) (IndexCounts a)
-indexCounts amount = dimap (\ (Index x) -> x) IndexCounts (Basic.countIndices amount)
diff --git a/library/Indexation/Functions.hs b/library/Indexation/Functions.hs
deleted file mode 100644
--- a/library/Indexation/Functions.hs
+++ /dev/null
@@ -1,55 +0,0 @@
-module Indexation.Functions
-where
-
-import Indexation.Prelude
-import Indexation.Types
-import qualified Data.Vector as Vector
-import qualified Data.HashMap.Strict as HashMap
-import qualified Data.Vector.Unboxed as UnboxedVector
-import qualified Data.Vector.Unboxed.Mutable as MutableUnboxedVector
-import qualified Data.Vector.Algorithms.Intro as IntroVectorAlgorithm
-import qualified Data.Bit as Bit
-import qualified Data.Vector.Unboxed.Bit as BitVec
-import qualified Indexation.Utils.BitVector as UnboxedVector
-import qualified Indexation.Utils.Unfoldr as Unfoldr
-
-
-lookupEntity :: Index entity -> EntityTable entity -> Maybe entity
-lookupEntity (Index indexPrim) (EntityTable vector) =
-  vector Vector.!? indexPrim
-
-lookupIndex :: (Eq entity, Hashable entity) => entity -> IndexTable entity -> Maybe (Index entity)
-lookupIndex entity (IndexTable _ hashMap) =
-  fmap Index (HashMap.lookup entity hashMap)
-
-createIndexSet :: (Eq entity, Hashable entity, Foldable foldable) => IndexTable entity -> foldable entity -> IndexSet entity
-createIndexSet (IndexTable size map) entities =
-  IndexSet (UnboxedVector.filledIndicesFoldable size (Unfoldr.hashMapValuesByKeys entities map))
-
-lookupInIndexSet :: Index entity -> IndexSet entity -> Bool
-lookupInIndexSet (Index indexInt) (IndexSet vec) = vec UnboxedVector.!? indexInt & maybe False Bit.toBool
-
-mergeIndexSets :: IndexSet entity -> IndexSet entity -> IndexSet entity
-mergeIndexSets (IndexSet a) (IndexSet b) = IndexSet (BitVec.intersection a b)
-
-topCountedIndexSet :: Int -> IndexCounts a -> IndexSet a
-topCountedIndexSet amount (IndexCounts countVec) = let
-  countVecLength = UnboxedVector.length countVec
-  limitedAmount = min amount countVecLength
-  in runST $ do
-    pairMVec <- UnboxedVector.unsafeThaw (UnboxedVector.imap (\ index count -> (count, index)) countVec)
-    IntroVectorAlgorithm.selectBy (\ a b -> compare (fst b) (fst a)) pairMVec limitedAmount
-    indexSetMVec <- MutableUnboxedVector.new countVecLength
-    forM_ [0..(pred limitedAmount)] $ \ pairIndex -> do
-      (_, index) <- MutableUnboxedVector.unsafeRead pairMVec pairIndex
-      MutableUnboxedVector.write indexSetMVec index (Bit.fromBool True)
-    IndexSet <$> UnboxedVector.unsafeFreeze indexSetMVec
-
-indexSetByMinCount :: Word32 -> IndexCounts a -> IndexSet a
-indexSetByMinCount min (IndexCounts countVec) = IndexSet (UnboxedVector.map (Bit.fromBool . (>= min)) countVec)
-
-countIndexSet :: IndexSet a -> Int
-countIndexSet (IndexSet vec) = BitVec.countBits vec
-
-invertIndexSet :: IndexSet a -> IndexSet a
-invertIndexSet (IndexSet vec) = IndexSet (BitVec.invert vec)
diff --git a/library/Indexation/IO.hs b/library/Indexation/IO.hs
--- a/library/Indexation/IO.hs
+++ b/library/Indexation/IO.hs
@@ -22,26 +22,26 @@
 import qualified Potoki.Cereal.Consume as PotokiConsume
 import qualified Potoki.Cereal.Produce as PotokiProduce
 import qualified Indexation.Potoki.Transform as PotokiTransform
-import qualified Indexation.Utils.Vector as Vector
-import qualified StmContainers.Map as StmMap
+import qualified Indexation.Vector as Vector
+import qualified Data.HashTable.IO as HashtablesIO
 import qualified Data.Serialize as Cereal
 import qualified Data.ByteString as ByteString
 
 
 createIndexer :: IO (Indexer entity)
 createIndexer = do
-  sizeVar <- newTVarIO 0
-  map <- StmMap.newIO
-  return (Indexer sizeVar map)
+  sizeRef <- newIORef 0
+  map <- HashtablesIO.new
+  return (Indexer sizeRef map)
 
 getIndexerSize :: Indexer entity -> IO Int
-getIndexerSize (Indexer sizeVar _) = atomically (readTVar sizeVar)
+getIndexerSize (Indexer sizeRef _) = readIORef sizeRef
 
 freezeIndexerAsVector :: Indexer entity -> IO (Vector entity)
-freezeIndexerAsVector (Indexer sizeVar map) =
+freezeIndexerAsVector (Indexer sizeRef map) =
   do
-    size <- atomically (readTVar sizeVar)
-    Vector.listTInIO size (hoist atomically (fmap swap (StmMap.listT map)))
+    size <- readIORef sizeRef
+    Vector.hashTable size map
 
 freezeIndexerAsEntityTable :: Indexer entity -> IO (EntityTable entity)
 freezeIndexerAsEntityTable = fmap EntityTable . freezeIndexerAsVector
diff --git a/library/Indexation/Instances.hs b/library/Indexation/Instances.hs
--- a/library/Indexation/Instances.hs
+++ b/library/Indexation/Instances.hs
@@ -4,14 +4,9 @@
 import Indexation.Prelude
 import Indexation.Types
 import Indexation.Instances.Cereal ()
-import Indexation.Functions
-import qualified Data.Vector.Unboxed.Bit as BitVec
 
 
 instance Show (Index a) where show (Index int) = show int
 deriving instance Eq (Index a)
 deriving instance Ord (Index a)
 deriving instance Hashable (Index a)
-
-instance Show (IndexSet a) where
-  show = show . BitVec.listBits . (\ (IndexSet x) -> x)
diff --git a/library/Indexation/Instances/Cereal.hs b/library/Indexation/Instances/Cereal.hs
--- a/library/Indexation/Instances/Cereal.hs
+++ b/library/Indexation/Instances/Cereal.hs
@@ -7,7 +7,6 @@
 import qualified Indexation.Cereal.Get as Get
 import qualified Indexation.Cereal.Put as Put
 import qualified Indexation.Constructors.EntityTable as EntityTable
-import qualified Data.Bit as Bit
 
 
 instance Serialize (Index a) where
@@ -21,9 +20,3 @@
 instance (Serialize entity, Eq entity, Hashable entity) => Serialize (IndexTable entity) where
   get = Get.getIndexTableAsEntityTable get
   put = Put.putEntityTable put . EntityTable.indexTable
-
-instance Serialize (IndexSet a) where
-  get = IndexSet <$> Get.getVector (Bit.fromBool <$> get)
-  put (IndexSet vector) = Put.putVector (put . Bit.toBool) vector
-
-deriving instance Serialize (IndexCounts a)
diff --git a/library/Indexation/Potoki/Produce.hs b/library/Indexation/Potoki/Produce.hs
deleted file mode 100644
--- a/library/Indexation/Potoki/Produce.hs
+++ /dev/null
@@ -1,28 +0,0 @@
-module Indexation.Potoki.Produce
-(
-  entities,
-  counts,
-  indexedCounts,
-)
-where
-
-import Indexation.Prelude
-import Indexation.Types
-import qualified Potoki.Produce as Produce
-import qualified Data.Vector.Generic as GenericVector
-
-
-entities :: EntityTable a -> Produce a
-entities (EntityTable vector) = Produce.vector vector
-
-{-|
-Counts in the index-order.
--}
-counts :: IndexCounts a -> Produce Word32
-counts (IndexCounts vector) = Produce.vector vector
-
-{-|
-Counts in the index-order paired with their indices.
--}
-indexedCounts :: IndexCounts a -> Produce (Int, Word32)
-indexedCounts (IndexCounts vector) = Produce.vectorWithIndices vector
diff --git a/library/Indexation/Potoki/Transform.hs b/library/Indexation/Potoki/Transform.hs
--- a/library/Indexation/Potoki/Transform.hs
+++ b/library/Indexation/Potoki/Transform.hs
@@ -14,25 +14,23 @@
 import Indexation.Instances ()
 import Potoki.Transform
 import qualified Focus
-import qualified StmContainers.Map as StmMap
+import qualified Data.HashTable.IO as HashtablesIO
 import qualified Data.Vector as Vector
 
 
 index :: (Eq entity, Hashable entity) => Indexer entity -> Transform entity (Index entity)
-index (Indexer sizeVar map) =
-  {-# SCC "index" #-} 
-  mapInIO $ \ entity -> atomically $ StmMap.focus focus entity map
+index (Indexer sizeRef map) =
+  mapInIO $ \ entity -> HashtablesIO.mutateIO map entity mutation
   where
-    focus = Focus.Focus conceal reveal where
-      conceal = do
-        size <- readTVar sizeVar
-        writeTVar sizeVar $! succ size
-        return (Index size, Focus.Set size)
-      reveal indexInt = return (Index indexInt, Focus.Leave)
+    mutation = \ case
+      Just indexInt -> return (Just indexInt, Index indexInt) 
+      Nothing -> do
+        size <- readIORef sizeRef
+        writeIORef sizeRef $! succ size
+        return (Just size, Index size)
 
 lookup :: EntityTable entity -> Transform (Index entity) (Maybe entity)
 lookup (EntityTable entityTableVector) =
-  {-# SCC "lookup" #-} 
   arr $ \ (Index indexInt) -> if Vector.length entityTableVector > indexInt
     then Just $! Vector.unsafeIndex entityTableVector indexInt
     else Nothing
diff --git a/library/Indexation/Predicate.hs b/library/Indexation/Predicate.hs
deleted file mode 100644
--- a/library/Indexation/Predicate.hs
+++ /dev/null
@@ -1,16 +0,0 @@
-module Indexation.Predicate
-where
-
-import Indexation.Prelude hiding (not)
-import Indexation.Types
-import Indexation.Instances ()
-import qualified Indexation.Prelude as Prelude
-import qualified Indexation.Utils.BitVector as UnboxedVector
-import qualified Indexation.Functions as Functions
-
-
-negated :: Predicate a -> Predicate a
-negated (Predicate fn) = Predicate (Prelude.not . fn)
-
-inIndexSet :: IndexSet a -> Predicate (Index a)
-inIndexSet indexSet = Predicate (\ index -> Functions.lookupInIndexSet index indexSet)
diff --git a/library/Indexation/Prelude.hs b/library/Indexation/Prelude.hs
--- a/library/Indexation/Prelude.hs
+++ b/library/Indexation/Prelude.hs
@@ -1,8 +1,6 @@
 module Indexation.Prelude
 (
   module Exports,
-  UnboxedVector,
-  BitVector,
 )
 where
 
@@ -84,14 +82,8 @@
 
 -- deferred-folds
 -------------------------
-import DeferredFolds.Unfoldl as Exports (Unfoldl(..))
-import DeferredFolds.UnfoldlM as Exports (UnfoldlM(..))
-import DeferredFolds.Unfoldr as Exports (Unfoldr(..))
-
--- contravariant
--------------------------
-import Data.Functor.Contravariant as Exports
-import Data.Functor.Contravariant.Divisible as Exports
+import DeferredFolds.Unfold as Exports (Unfold(..))
+import DeferredFolds.UnfoldM as Exports (UnfoldM(..))
 
 -- hashable
 -------------------------
@@ -109,10 +101,6 @@
 -------------------------
 import Data.Serialize as Exports (Serialize)
 
--- cereal-vector
--------------------------
-import Data.Vector.Serialize ()
-
 -- bytestring
 -------------------------
 import Data.ByteString as Exports (ByteString)
@@ -134,21 +122,3 @@
 -- mmorph
 -------------------------
 import Control.Monad.Morph as Exports hiding (MonadTrans(..))
-
--- list-t
--------------------------
-import ListT as Exports (ListT(..))
-
--- bitvec
--------------------------
-import Data.Bit as Exports (Bit)
-
--- 
--------------------------
-import qualified Data.Vector.Unboxed.Bit as BitVec
-import qualified Data.Vector.Unboxed as UnboxedVector
-
-
-type UnboxedVector = UnboxedVector.Vector
-
-type BitVector = UnboxedVector Bit
diff --git a/library/Indexation/Types.hs b/library/Indexation/Types.hs
--- a/library/Indexation/Types.hs
+++ b/library/Indexation/Types.hs
@@ -2,23 +2,13 @@
 where
 
 import Indexation.Prelude
-import qualified StmContainers.Map as StmMap
-import qualified Data.Vector.Unboxed as UnboxedVector
-import qualified Data.Vector.Unboxed.Bit as BitVec
+import qualified Data.HashTable.IO as HashtablesIO
 
 
-data Indexer entity = Indexer {-# UNPACK #-} !(TVar Int) {-# UNPACK #-} !(StmMap.Map entity Int)
+data Indexer entity = Indexer {-# UNPACK #-} !(IORef Int) {-# UNPACK #-} !(HashtablesIO.CuckooHashTable entity Int)
 
 data IndexTable entity = IndexTable {-# UNPACK #-} !Int {-# UNPACK #-} !(HashMap entity Int)
 
 newtype EntityTable entity = EntityTable (Vector entity)
 
 newtype Index entity = Index Int
-
-{-|
-Set of indices.
-A more efficient alternative to @HashSet (Index entity)@.
--}
-newtype IndexSet entity = IndexSet (BitVec.Vector BitVec.Bit)
-
-newtype IndexCounts entity = IndexCounts (UnboxedVector.Vector Word32)
diff --git a/library/Indexation/Utils/BitVector.hs b/library/Indexation/Utils/BitVector.hs
deleted file mode 100644
--- a/library/Indexation/Utils/BitVector.hs
+++ /dev/null
@@ -1,15 +0,0 @@
-module Indexation.Utils.BitVector
-where
-
-import Indexation.Prelude hiding (Vector)
-import Data.Vector.Unboxed hiding (forM_)
-import qualified Data.Vector.Unboxed.Mutable as MutableUnboxedVector
-import qualified Data.Bit as Bit
-
-
-filledIndicesFoldable :: Foldable foldable => Int -> foldable Int -> Vector Bit
-filledIndicesFoldable size foldable = runST $ do
-  mv <- MutableUnboxedVector.new size
-  forM_ foldable $ \ index -> do
-    MutableUnboxedVector.unsafeWrite mv index (Bit.fromBool True)
-  unsafeFreeze mv
diff --git a/library/Indexation/Utils/Unfoldr.hs b/library/Indexation/Utils/Unfoldr.hs
deleted file mode 100644
--- a/library/Indexation/Utils/Unfoldr.hs
+++ /dev/null
@@ -1,21 +0,0 @@
-module Indexation.Utils.Unfoldr
-where
-
-import Indexation.Prelude
-import DeferredFolds.Unfoldr
-import qualified Data.HashMap.Strict as HashMap
-import qualified Data.Vector.Unboxed.Bit as BitVec
-
-
-hashMapAt :: (Hashable a, Eq a) => a -> HashMap a b -> Unfoldr b
-hashMapAt a = foldable . HashMap.lookup a
-
-hashMapValuesByKeys :: (Hashable a, Eq a, Foldable foldable) => foldable a -> HashMap a b -> Unfoldr b
-hashMapValuesByKeys keys hashMap = do
-  key <- foldable keys
-  hashMapAt key hashMap
-
-bitVecWords :: BitVector -> Unfoldr Word
-bitVecWords vec = do
-  index <- intsInRange 0 (pred (BitVec.wordLength vec))
-  return (BitVec.indexWord vec index)
diff --git a/library/Indexation/Utils/Vector.hs b/library/Indexation/Utils/Vector.hs
deleted file mode 100644
--- a/library/Indexation/Utils/Vector.hs
+++ /dev/null
@@ -1,61 +0,0 @@
-module Indexation.Utils.Vector
-where
-
-import Indexation.Prelude
-import Data.Vector
-import qualified Data.Vector.Mutable as MutableVector
-import qualified Data.HashMap.Strict as HashMap
-import qualified DeferredFolds.UnfoldlM as UnfoldlM
-import qualified ListT
-
-
-{-|
-This function is not tested.
--}
-{-# NOINLINE populate #-}
-populate :: Monad effect => Int -> effect (Int, element) -> effect (Vector element)
-populate size effect =
-  do
-    mv <- return (unsafeDupablePerformIO (MutableVector.unsafeNew size))
-    let
-      loop stepsRemaining =
-        if stepsRemaining > 0
-          then do
-            (index, element) <- effect
-            () <- return (unsafeDupablePerformIO (MutableVector.write mv index element))
-            loop (pred stepsRemaining)
-          else do
-            !v <- return (unsafeDupablePerformIO (freeze mv))
-            return v
-      in loop size
-
-{-|
-This function is partial. It doesn't check the size or indices.
--}
-{-# INLINE indexHashMapWithSize #-}
-indexHashMapWithSize :: Int -> HashMap element Int -> Vector element
-indexHashMapWithSize size hashMap =
-  runST $ do
-    mv <- MutableVector.new size
-    HashMap.foldrWithKey
-      (\ element index action -> MutableVector.write mv index element >> action)
-      (return ())
-      hashMap
-    freeze mv
-
-{-# NOINLINE unfoldlM #-}
-unfoldlM :: Monad m => Int -> UnfoldlM m (Int, element) -> m (Vector element)
-unfoldlM size unfoldlM =
-  let
-    step mv (index, element) = return (unsafeDupablePerformIO (MutableVector.write mv index element $> mv))
-    in do
-      !mv <- return (unsafeDupablePerformIO (MutableVector.unsafeNew size))
-      UnfoldlM.foldlM' step mv unfoldlM
-      !iv <- return (unsafeDupablePerformIO (unsafeFreeze mv))
-      return iv
-
-listTInIO :: Int -> ListT IO (Int, element) -> IO (Vector element)
-listTInIO size listT = do
-  mv <- MutableVector.unsafeNew size
-  flip ListT.traverse_ listT $ \ (index, element) -> MutableVector.write mv index element
-  unsafeFreeze mv
diff --git a/library/Indexation/Vector.hs b/library/Indexation/Vector.hs
new file mode 100644
--- /dev/null
+++ b/library/Indexation/Vector.hs
@@ -0,0 +1,60 @@
+module Indexation.Vector
+where
+
+import Indexation.Prelude
+import Data.Vector
+import qualified Data.Vector.Mutable as MutableVector
+import qualified Data.HashMap.Strict as HashMap
+import qualified DeferredFolds.UnfoldM as UnfoldM
+import qualified Data.HashTable.IO as HashtablesIO
+
+
+{-|
+This function is not tested.
+-}
+{-# NOINLINE populate #-}
+populate :: Monad effect => Int -> effect (Int, element) -> effect (Vector element)
+populate size effect =
+  do
+    mv <- return (unsafeDupablePerformIO (MutableVector.unsafeNew size))
+    let
+      loop stepsRemaining =
+        if stepsRemaining > 0
+          then do
+            (index, element) <- effect
+            () <- return (unsafeDupablePerformIO (MutableVector.write mv index element))
+            loop (pred stepsRemaining)
+          else do
+            !v <- return (unsafeDupablePerformIO (freeze mv))
+            return v
+      in loop size
+
+{-|
+This function is partial. It doesn't check the size or indices.
+-}
+{-# INLINE indexHashMapWithSize #-}
+indexHashMapWithSize :: Int -> HashMap element Int -> Vector element
+indexHashMapWithSize size hashMap =
+  unsafePerformIO $ do
+    mv <- MutableVector.unsafeNew size
+    let
+      step () element index = unsafeDupablePerformIO (MutableVector.write mv index element)
+      !() = HashMap.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 (MutableVector.write mv index element $> mv))
+    in do
+      !mv <- return (unsafeDupablePerformIO (MutableVector.unsafeNew size))
+      UnfoldM.foldlM' step mv unfoldM
+      !iv <- return (unsafeDupablePerformIO (unsafeFreeze mv))
+      return iv
+
+hashTable :: Int -> HashtablesIO.CuckooHashTable element Int -> IO (Vector element)
+hashTable size hashTable = do
+  mv <- MutableVector.unsafeNew size
+  flip HashtablesIO.mapM_ hashTable $ \ (element, index) -> MutableVector.write mv index element
+  unsafeFreeze mv
