diff --git a/library/VectorBuilder/MVector.hs b/library/VectorBuilder/MVector.hs
--- a/library/VectorBuilder/MVector.hs
+++ b/library/VectorBuilder/MVector.hs
@@ -4,19 +4,20 @@
 where
 
 import VectorBuilder.Private.Prelude
-import Data.Vector.Mutable
+import Data.Vector.Generic.Mutable
 import qualified VectorBuilder.Private.Builder as A
-import qualified VectorBuilder.Private.Action as B
+import qualified VectorBuilder.Private.SizeTrackingAction as B
+import qualified VectorBuilder.Private.Action as C
 
 
 -- |
 -- Construct a mutable vector from a builder.
 {-# INLINABLE build #-}
-build :: A.Builder element -> ST s (MVector s element)
-build (A.Builder (B.Action actionFn)) =
-  case actionFn 0 of
-    (updateFn, size) ->
+build :: MVector vector element => A.Builder element -> ST s (vector s element)
+build (A.Builder (B.SizeTrackingAction sizeTrackingActionFn)) =
+  case sizeTrackingActionFn 0 of
+    (C.Action actionFn, size) ->
       do
         vector <- unsafeNew size
-        updateFn vector
+        actionFn vector
         return vector
diff --git a/library/VectorBuilder/Private/Action.hs b/library/VectorBuilder/Private/Action.hs
--- a/library/VectorBuilder/Private/Action.hs
+++ b/library/VectorBuilder/Private/Action.hs
@@ -2,43 +2,24 @@
 where
 
 import VectorBuilder.Private.Prelude
-import qualified Data.Vector.Mutable as A
-import qualified Data.Vector as B
+import qualified Data.Vector.Generic.Mutable as A
+import qualified Data.Vector.Generic as B
 
 
-newtype Action s element result =
-  Action (Int -> (A.MVector s element -> ST s result, Int))
-
-instance Functor (Action s element) where
-  fmap fn (Action actionFn) =
-    Action $ \size ->
-    case actionFn size of
-      (updateFn, newSize) ->
-        (fmap fn . updateFn, newSize)
+newtype Action element result =
+  Action (forall s vector. A.MVector vector element => vector s element -> ST s result)
+  deriving (Functor)
 
-instance Applicative (Action s element) where
+instance Applicative (Action element) where
   pure result =
-    Action (\size -> (const (pure result), size))
+    Action (const (pure result))
   (<*>) (Action actionFn1) (Action actionFn2) =
-    Action actionFn
-    where
-      actionFn size =
-        case actionFn1 size of
-          (vectorFn1, size1) ->
-            case actionFn2 size1 of
-              (vectorFn2, size2) ->
-                ((<*>) <$> vectorFn1 <*> vectorFn2, size2)
-
+    Action ((<*>) <$> actionFn1 <*> actionFn2)
 
-snoc :: element -> Action s element ()
-snoc element =
-  Action (\size -> (\mVector -> A.unsafeWrite mVector size element, succ size))
+unsafeWrite :: Int -> element -> Action element ()
+unsafeWrite index element =
+  Action (\mVector -> A.unsafeWrite mVector index element)
 
-append :: B.Vector element -> Action s element ()
-append appendedVector =
-  Action ((,) <$> vectorFn <*> size)
-  where
-    vectorFn currentSize mVector =
-      B.ifoldM' (\_ index element -> A.unsafeWrite mVector (currentSize + index) element) () appendedVector
-    size currentSize =
-      B.length appendedVector + currentSize
+unsafeWriteMany :: B.Vector vector element => Int -> vector element -> Action element ()
+unsafeWriteMany startingIndex appendedVector =
+  Action (\mVector -> B.ifoldM' (\_ index element -> A.unsafeWrite mVector (startingIndex + index) element) () appendedVector)
diff --git a/library/VectorBuilder/Private/Builder.hs b/library/VectorBuilder/Private/Builder.hs
--- a/library/VectorBuilder/Private/Builder.hs
+++ b/library/VectorBuilder/Private/Builder.hs
@@ -2,7 +2,7 @@
 where
 
 import VectorBuilder.Private.Prelude
-import qualified VectorBuilder.Private.Action as A
+import qualified VectorBuilder.Private.SizeTrackingAction as A
 import qualified Data.Vector as B
 
 
@@ -11,7 +11,7 @@
 -- 
 -- It postpones the actual construction of a vector until the execution of the builder.
 newtype Builder element =
-  Builder (forall s. A.Action s element ())
+  Builder (A.SizeTrackingAction element ())
 
 -- |
 -- Provides support for /O(1)/ concatenation.
diff --git a/library/VectorBuilder/Private/SizeTrackingAction.hs b/library/VectorBuilder/Private/SizeTrackingAction.hs
new file mode 100644
--- /dev/null
+++ b/library/VectorBuilder/Private/SizeTrackingAction.hs
@@ -0,0 +1,38 @@
+module VectorBuilder.Private.SizeTrackingAction
+where
+
+import VectorBuilder.Private.Prelude
+import qualified Data.Vector.Mutable as A
+import qualified Data.Vector as B
+import qualified VectorBuilder.Private.Action as C
+
+
+newtype SizeTrackingAction element result =
+  SizeTrackingAction (Int -> (C.Action element result, Int))
+  deriving (Functor)
+
+instance Applicative (SizeTrackingAction element) where
+  pure result =
+    SizeTrackingAction (\size -> (pure result, size))
+  (<*>) (SizeTrackingAction sizeTrackingActionFn1) (SizeTrackingAction sizeTrackingActionFn2) =
+    SizeTrackingAction sizeTrackingActionFn
+    where
+      sizeTrackingActionFn size =
+        case sizeTrackingActionFn1 size of
+          (action1, size1) ->
+            case sizeTrackingActionFn2 size1 of
+              (action2, size2) ->
+                (action1 <*> action2, size2)
+
+snoc :: element -> SizeTrackingAction element ()
+snoc element =
+  SizeTrackingAction (\size -> (C.unsafeWrite size element, succ size))
+
+append :: B.Vector element -> SizeTrackingAction element ()
+append appendedVector =
+  SizeTrackingAction ((,) <$> action <*> size)
+  where
+    action currentSize =
+      C.unsafeWriteMany currentSize appendedVector
+    size currentSize =
+      B.length appendedVector + currentSize
diff --git a/library/VectorBuilder/Vector.hs b/library/VectorBuilder/Vector.hs
--- a/library/VectorBuilder/Vector.hs
+++ b/library/VectorBuilder/Vector.hs
@@ -4,7 +4,7 @@
 where
 
 import VectorBuilder.Private.Prelude
-import Data.Vector
+import Data.Vector.Generic
 import qualified VectorBuilder.Private.Builder as A
 import qualified VectorBuilder.MVector as B
 
@@ -12,6 +12,6 @@
 -- |
 -- Construct a vector from a builder.
 {-# INLINE build #-}
-build :: A.Builder element -> Vector element
+build :: Vector vector element => A.Builder element -> vector element
 build builder =
   runST (B.build builder >>= unsafeFreeze)
diff --git a/vector-builder.cabal b/vector-builder.cabal
--- a/vector-builder.cabal
+++ b/vector-builder.cabal
@@ -1,11 +1,36 @@
 name:
   vector-builder
 version:
-  0.1.1
+  0.2
 synopsis:
   Vector builder
 description:
-  An API for efficient construction of vectors with abstraction over their size.
+  An API for efficient and convenient construction of vectors.
+  It provides the composable `Builder` abstraction, which has instances of the `Monoid` and `Semigroup` classes. 
+  .
+  [Usage]
+  .
+  First you use the `Builder` abstraction to specify the structure of the vector.
+  Then you execute the builder to actually produce the vector.
+  .
+  [Example]
+  .
+  The following code shows how you can efficiently concatenate different datastructures into a single immutable vector:
+  .
+  >
+  >import qualified Data.Vector as A
+  >import qualified VectorBuilder.Builder as B
+  >import qualified VectorBuilder.Vector as C
+  >
+  >
+  >myVector :: A.Vector a -> [a] -> a -> A.Vector a
+  >myVector vector list element =
+  >  C.build builder
+  >  where
+  >    builder =
+  >      B.vector vector <>
+  >      foldMap B.singleton list <>
+  >      B.singleton element
 category:
   Vector
 homepage:
@@ -45,6 +70,7 @@
   other-modules:
     VectorBuilder.Private.Prelude
     VectorBuilder.Private.Action
+    VectorBuilder.Private.SizeTrackingAction
     VectorBuilder.Private.Builder
   exposed-modules:
     VectorBuilder.Builder
