diff --git a/library/PtrPoker/Poke.hs b/library/PtrPoker/Poke.hs
--- a/library/PtrPoker/Poke.hs
+++ b/library/PtrPoker/Poke.hs
@@ -14,6 +14,11 @@
     Poke $ \ p -> foldM (\ p (Poke poker) -> poker p) p foldable
   #-}
 
+{-|
+Abstraction over an IO action,
+which takes a pointer, populates it and
+produces a pointer right after the populated data.
+-}
 newtype Poke =
   Poke { pokePtr :: Ptr Word8 -> IO (Ptr Word8) }
 
@@ -31,36 +36,55 @@
   mconcat =
     concat
 
+{-|
+Reuses the IsString instance of 'ByteString'.
+-}
 instance IsString Poke where
   fromString = byteString . fromString
 
+{-|
+Concatenate a foldable of pokes.
+-}
 {-# INLINE[1] concat #-}
 concat :: Foldable f => f Poke -> Poke
 concat pokers =
   Poke (\ p -> foldM (\ p (Poke io) -> io p) p pokers)
 
+{-|
+Efficiently copy the contents of ByteString using @memcpy@.
+-}
 {-# INLINE byteString #-}
 byteString :: ByteString -> Poke
 byteString bs =
   Poke $ \ ptr -> inline ByteStringIO.pokeByteString ptr bs
 
+{-|
+Encode Word8 as byte, incrementing the pointer by 1.
+-}
 {-# INLINE[1] word8 #-}
 word8 :: Word8 -> Poke
 word8 a =
   Poke (\ p -> PrimIO.pokeWord8 p a $> plusPtr p 1)
 
-{-| Little-endian Word64 poker. -}
+{-|
+Encode Word64 in Little-endian.
+-}
 {-# INLINE[1] lWord64 #-}
 lWord64 :: Word64 -> Poke
 lWord64 a =
   Poke (\ p -> PrimIO.pokeLEWord64 p a $> plusPtr p 8)
 
-{-| Big-endian Word64 poker. -}
+{-|
+Encode Word64 in Big-endian.
+-}
 {-# INLINE[1] bWord64 #-}
 bWord64 :: Word64 -> Poke
 bWord64 a =
   Poke (\ p -> PrimIO.pokeBEWord64 p a $> plusPtr p 8)
 
+{-|
+Encode Text in UTF8.
+-}
 {-# INLINE textUtf8 #-}
 textUtf8 :: Text -> Poke
 textUtf8 (Text.Text arr off len) =
@@ -70,56 +94,89 @@
 -- * ASCII integers
 -------------------------
 
+{-|
+Encode Int8 as a signed ASCII decimal.
+-}
 {-# INLINE[1] int8AsciiDec #-}
 int8AsciiDec :: Int8 -> Poke
 int8AsciiDec a =
   Poke (Ffi.pokeIntInDec (fromIntegral a))
 
+{-|
+Encode Int16 as a signed ASCII decimal.
+-}
 {-# INLINE[1] int16AsciiDec #-}
 int16AsciiDec :: Int16 -> Poke
 int16AsciiDec a =
   Poke (Ffi.pokeIntInDec (fromIntegral a))
 
+{-|
+Encode Int32 as a signed ASCII decimal.
+-}
 {-# INLINE[1] int32AsciiDec #-}
 int32AsciiDec :: Int32 -> Poke
 int32AsciiDec a =
   Poke (Ffi.pokeIntInDec (fromIntegral a))
 
+{-|
+Encode Int64 as a signed ASCII decimal.
+-}
 {-# INLINE[1] int64AsciiDec #-}
 int64AsciiDec :: Int64 -> Poke
 int64AsciiDec a =
   Poke (Ffi.pokeLongLongIntInDec (fromIntegral a))
 
+{-|
+Encode Int as a signed ASCII decimal.
+-}
 {-# INLINE[1] intAsciiDec #-}
 intAsciiDec :: Int -> Poke
 intAsciiDec a =
   Poke (Ffi.pokeLongLongIntInDec (fromIntegral a))
 
+{-|
+Encode Word8 as an unsigned ASCII decimal.
+-}
 {-# INLINE[1] word8AsciiDec #-}
 word8AsciiDec :: Word8 -> Poke
 word8AsciiDec a =
   Poke (Ffi.pokeUIntInDec (fromIntegral a))
 
+{-|
+Encode Word16 as an unsigned ASCII decimal.
+-}
 {-# INLINE[1] word16AsciiDec #-}
 word16AsciiDec :: Word16 -> Poke
 word16AsciiDec a =
   Poke (Ffi.pokeUIntInDec (fromIntegral a))
 
+{-|
+Encode Word32 as an unsigned ASCII decimal.
+-}
 {-# INLINE[1] word32AsciiDec #-}
 word32AsciiDec :: Word32 -> Poke
 word32AsciiDec a =
   Poke (Ffi.pokeUIntInDec (fromIntegral a))
 
+{-|
+Encode Word64 as an unsigned ASCII decimal.
+-}
 {-# INLINE[1] word64AsciiDec #-}
 word64AsciiDec :: Word64 -> Poke
 word64AsciiDec a =
   Poke (Ffi.pokeLongLongUIntInDec (fromIntegral a))
 
+{-|
+Encode Word as an unsigned ASCII decimal.
+-}
 {-# INLINE[1] wordAsciiDec #-}
 wordAsciiDec :: Word -> Poke
 wordAsciiDec a =
   Poke (Ffi.pokeLongLongUIntInDec (fromIntegral a))
 
+{-|
+Encode Double as a signed ASCII decimal.
+-}
 {-# INLINE doubleAsciiDec #-}
 doubleAsciiDec :: Double -> Poke
 doubleAsciiDec a =
@@ -133,7 +190,12 @@
 
 {-|
 Having the amount of bytes to be written precomputed,
-executes an action, which fills the pointer going downward.
+executes an action,
+which fills the pointer going downward,
+starting from the pointer that follows the chunk.
+I.e., you have to decrement the pointer
+before writing the first byte,
+decrement it again before writing the second byte and so on.
 -}
 {-# INLINE sizedReverse #-}
 sizedReverse :: Int -> (Ptr Word8 -> IO a) -> Poke
diff --git a/library/PtrPoker/Size.hs b/library/PtrPoker/Size.hs
--- a/library/PtrPoker/Size.hs
+++ b/library/PtrPoker/Size.hs
@@ -10,6 +10,14 @@
 import qualified PtrPoker.Ffi as Ffi
 
 
+{-|
+Efficiently count the amount of bytes required to encode Word64
+as a decimal number in ASCII.
+
+Implemented as a balanced tree of \"ifs\"
+centered around the middle of the range.
+This is much faster than anything based on logarithms.
+-}
 {-# INLINE word64AsciiDec #-}
 word64AsciiDec :: Word64 -> Int
 word64AsciiDec x =
@@ -53,6 +61,14 @@
           then 2
           else 1
 
+{-|
+Efficiently count the amount of bytes required to encode Int64
+as a signed decimal number in ASCII.
+
+Implemented as a balanced tree of \"ifs\"
+centered around the middle of the range.
+This is much faster than anything based on logarithms.
+-}
 {-# INLINE int64AsciiDec #-}
 int64AsciiDec :: Int64 -> Int
 int64AsciiDec x =
@@ -132,6 +148,10 @@
             then 2
             else 1
 
+{-|
+Efficiently count the amount of bytes required to encode Text
+in UTF8.
+-}
 {-# INLINE textUtf8 #-}
 textUtf8 :: Text -> Int
 textUtf8 (Text.Text arr off len) =
diff --git a/library/PtrPoker/Write.hs b/library/PtrPoker/Write.hs
--- a/library/PtrPoker/Write.hs
+++ b/library/PtrPoker/Write.hs
@@ -12,13 +12,16 @@
 import qualified Data.ByteString.Internal as ByteString
 
 
+{-|
+Execute Write, producing strict ByteString.
+-}
 {-# INLINABLE writeToByteString #-}
 writeToByteString :: Write -> ByteString
 writeToByteString Write{..} =
   ByteString.unsafeCreate writeSize (void . Poke.pokePtr writePoke)
 
 {-|
-Specification of how much bytes to allocate and how to populate them.
+Specification of how many bytes to allocate and how to populate them.
 
 Useful for creating strict bytestrings and tasks like that.
 -}
@@ -38,16 +41,25 @@
   mempty =
     Write 0 mempty
 
+{-|
+Reuses the IsString instance of 'ByteString'.
+-}
 instance IsString Write where
   {-# INLINE fromString #-}
   fromString =
     byteString . fromString
 
+{-|
+Render Word8 as byte.
+-}
 {-# INLINE word8 #-}
 word8 :: Word8 -> Write
 word8 a =
   Write 1 (Poke.word8 a)
 
+{-|
+Render Word64 in ASCII decimal.
+-}
 {-# INLINE word64AsciiDec #-}
 word64AsciiDec :: Word64 -> Write
 word64AsciiDec a =
@@ -58,11 +70,17 @@
     poke =
       Poke.sizedReverse size (Ffi.revPokeUInt64 (fromIntegral a))
 
+{-|
+Render Word in ASCII decimal.
+-}
 {-# INLINE wordAsciiDec #-}
 wordAsciiDec :: Word -> Write
 wordAsciiDec =
   word64AsciiDec . fromIntegral
 
+{-|
+Render Int64 in ASCII decimal.
+-}
 {-# INLINE int64AsciiDec #-}
 int64AsciiDec :: Int64 -> Write
 int64AsciiDec a =
@@ -73,6 +91,9 @@
     poke =
       Poke.sizedReverse size (Ffi.revPokeInt64 (fromIntegral a))
 
+{-|
+Render Int in ASCII decimal.
+-}
 {-# INLINE intAsciiDec #-}
 intAsciiDec :: Int -> Write
 intAsciiDec =
@@ -112,18 +133,37 @@
       then word8 45 <> byteString (ByteString.double (negate a))
       else byteString (ByteString.double a)
 
+{-|
+Render Scientific in ASCII decimal.
+-}
 {-# INLINE scientificAsciiDec #-}
 scientificAsciiDec :: Scientific -> Write
 scientificAsciiDec =
   byteString . ByteString.scientific
 
+{-|
+Efficiently copy the contents of ByteString using @memcpy@.
+-}
 {-# INLINE byteString #-}
 byteString :: ByteString -> Write
 byteString a =
   Write (ByteString.length a) (inline Poke.byteString a)
 
 {-|
-Benchmark results in comparison to @Data.Text.Encoding.'Data.Text.Encoding.decodeUtf8'@.
+Render Text in UTF8.
+
+Does pretty much the same as 'Data.Text.Encoding.encodeUtf8',
+both implementation and performance-wise,
+while allowing you to avoid redundant @memcpy@
+compared to @('byteString' . 'Data.Text.Encoding.encodeUtf8')@.
+
+Following are the benchmark results comparing the performance of
+@('writeToByteString' . 'textUtf8')@ with
+@Data.Text.Encoding.'Data.Text.Encoding.encodeUtf8'@
+on inputs in Latin and Greek (requiring different number of surrogate bytes).
+The results show that they are quite similar.
+
+=== __Benchmark results__
 
 > textUtf8/ptr-poker/latin/1               mean 57.06 ns  ( +- 3.283 ns  )
 > textUtf8/ptr-poker/latin/10              mean 214.1 ns  ( +- 8.601 ns  )
diff --git a/ptr-poker.cabal b/ptr-poker.cabal
--- a/ptr-poker.cabal
+++ b/ptr-poker.cabal
@@ -1,5 +1,5 @@
 name: ptr-poker
-version: 0.1.1.1
+version: 0.1.1.2
 synopsis: Pointer poking action construction and composition toolkit
 homepage: https://github.com/nikita-volkov/ptr-poker
 bug-reports: https://github.com/nikita-volkov/ptr-poker/issues
