diff --git a/library/Ptr/Parse.hs b/library/Ptr/Parse.hs
--- a/library/Ptr/Parse.hs
+++ b/library/Ptr/Parse.hs
@@ -182,7 +182,9 @@
             else do
               bytes <- B.packCStringLen (castPtr ptr, availableAmount - unconsumedAmount)
               succeed bytes unconsumedAmount currentPtr
-        else failWithEOI 0
+        else do
+          bytes <- B.packCStringLen (castPtr ptr, availableAmount - unconsumedAmount)
+          succeed bytes unconsumedAmount currentPtr
     in iterate availableAmount availableAmount ptr
 
 {-# INLINE skipWhile #-}
@@ -198,7 +200,7 @@
           if predicate byte
             then iterate availableAmount (pred unconsumedAmount) (plusPtr ptr 1)
             else succeed () unconsumedAmount ptr
-        else failWithEOI 0
+        else succeed () unconsumedAmount ptr
     in iterate availableAmount availableAmount ptr
 
 {-# INLINE foldWhile #-}
diff --git a/library/Ptr/Poking.hs b/library/Ptr/Poking.hs
--- a/library/Ptr/Poking.hs
+++ b/library/Ptr/Poking.hs
@@ -8,6 +8,8 @@
 import qualified Ptr.PokeIO as E
 import qualified Data.ByteString.Internal as B
 import qualified Data.Vector as F
+import qualified Data.Vector.Generic as GenericVector
+import qualified Data.List as List
 
 
 {-|
@@ -45,6 +47,11 @@
   mappend =
     (<>)
 
+instance IsString Poking where
+  fromString string = Poking (List.length string) io where
+    io ptr = foldM_ step ptr string where
+      step ptr char = A.pokeWord8 ptr (fromIntegral (ord char)) $> plusPtr ptr 1
+
 {-# INLINE null #-}
 null :: Poking -> Bool
 null =
@@ -172,21 +179,38 @@
         _ -> state <> word8 0
 
 {-# INLINABLE vector #-}
-vector :: (element -> Poking) -> F.Vector element -> Poking
+vector :: GenericVector.Vector vector element => (element -> Poking) -> vector element -> Poking
 vector element vectorValue =
   Poking byteSize io
   where
     byteSize =
-      foldl' step 0 vectorValue
+      GenericVector.foldl' step 0 vectorValue
       where
         step !byteSize elementValue =
           case element elementValue of
             Poking elementByteSize _ -> byteSize + elementByteSize
     io ptr =
-      F.foldM'_ step ptr vectorValue
+      GenericVector.foldM'_ step ptr vectorValue
       where
         step ptr elementValue =
           case element elementValue of
             Poking elementByteSize elementIO -> do
               elementIO ptr
               return (plusPtr ptr elementByteSize)
+
+{-# INLINABLE intercalateVector #-}
+intercalateVector :: GenericVector.Vector vector element => (element -> Poking) -> Poking -> vector element -> Poking
+intercalateVector element (Poking separatorLength separatorIo) vectorValue = Poking length io where
+  length = GenericVector.foldl' step 0 vectorValue + ((GenericVector.length vectorValue - 1) * separatorLength) where
+    step length elementValue = case element elementValue of
+      Poking elementLength _ -> length + elementLength
+  indexIsLast = let
+    lastIndex = pred (GenericVector.length vectorValue)
+    in (== lastIndex)
+  io ptr = GenericVector.ifoldM'_ step ptr vectorValue where
+    step ptr index elementValue = case element elementValue of
+      Poking elementLength elementIo -> if indexIsLast index
+        then elementIo ptr $> ptr
+        else let
+          ptrAfterElement = plusPtr ptr elementLength
+          in elementIo ptr *> separatorIo ptrAfterElement $> plusPtr ptrAfterElement separatorLength
diff --git a/ptr.cabal b/ptr.cabal
--- a/ptr.cabal
+++ b/ptr.cabal
@@ -1,7 +1,7 @@
 name:
   ptr
 version:
-  0.16.5
+  0.16.6
 category:
   Ptr, Data
 synopsis:
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -14,6 +14,7 @@
 import qualified Ptr.Poking as F
 import qualified Ptr.Parse as G
 import qualified Data.ByteString as D
+import qualified Data.Vector.Unboxed as UnboxedVector
 
 
 main =
@@ -39,6 +40,12 @@
       ,
       testCase "asciiUtcTimeInIso8601" $ do
         assertEqual "" "2017-02-01T05:03:58Z" (A.poking (F.asciiUtcTimeInIso8601 (read "2017-02-01 05:03:58")))
+      ,
+      testCase "fromString" $ do
+        assertEqual "" "123" (A.poking "123")
+      ,
+      testCase "intercalateVector" $ do
+        assertEqual "" "1,2,3,4" (A.poking (F.intercalateVector F.asciiIntegral "," (UnboxedVector.fromList [1 :: Word8, 2, 3, 4])))
     ]
     ,
     parsing
@@ -46,12 +53,16 @@
 
 parsing :: TestTree
 parsing =
-  testGroup "Parsing" $
-  [
-    testCase "bytesWhile" $ assertEqual "" "123" (A.parse "123456" (G.bytesWhile (< 52)) undefined undefined)
-    ,
-    testCase "bytesWhile 2" $ assertEqual "" "123456" (A.parse "123456" (G.bytesWhile (< 59)) undefined undefined)
-  ]
+  testGroup "Parsing" $ let
+    assertParsesTo expected input parser =
+      assertEqual "" (Right expected) (A.parse input (fmap Right parser) (Left . Left) (Left . Right))
+    in [
+        testCase "bytesWhile" $ assertParsesTo "123" "123456" $ G.bytesWhile (< 52)
+        ,
+        testCase "bytesWhile on full input" $ assertParsesTo "123456" "123456" $ G.bytesWhile (< 59)
+        ,
+        testCase "skipWhile on full input" $ assertParsesTo () "123456" $ G.skipWhile (< 59)
+      ]
 
 pokeThenPeek :: B.Poke a -> C.Peek a -> Maybe (a -> a)
 pokeThenPeek (B.Poke pokeSize pokeIO) (C.Peek peekSize peekIO) =
