diff --git a/library/TextBuilderDev.hs b/library/TextBuilderDev.hs
--- a/library/TextBuilderDev.hs
+++ b/library/TextBuilderDev.hs
@@ -1,5 +1,5 @@
 module TextBuilderDev
-  ( -- *
+  ( -- * --
     TextBuilder,
 
     -- * Accessors
@@ -18,6 +18,7 @@
     -- ** Builder manipulators
     force,
     intercalate,
+    intercalateMap,
     padFromLeft,
     padFromRight,
 
@@ -92,7 +93,7 @@
 import qualified Data.Text.Lazy as TextLazy
 import qualified Data.Text.Lazy.Builder as TextLazyBuilder
 
--- *
+-- * --
 
 -- |
 -- Evidence that there exists an unambiguous way to convert
@@ -142,7 +143,7 @@
   toTextBuilder = text . TextLazy.toStrict . TextLazyBuilder.toLazyText
   fromTextBuilder = TextLazyBuilder.fromText . buildText
 
--- *
+-- * --
 
 -- |
 -- Specification of how to efficiently construct strict 'Text'.
@@ -368,6 +369,7 @@
         B.copyI builderArray builderOffset array offset (builderOffset + length)
 #endif
 
+-- | Lazy text
 {-# INLINE lazyText #-}
 lazyText :: TextLazy.Text -> TextBuilder
 lazyText =
@@ -491,7 +493,7 @@
 
 -- | Intercalate builders
 {-# INLINE intercalate #-}
-intercalate :: Foldable foldable => TextBuilder -> foldable TextBuilder -> TextBuilder
+intercalate :: Foldable f => TextBuilder -> f TextBuilder -> TextBuilder
 intercalate separator = extract . foldl' step init
   where
     init = Product2 False mempty
@@ -501,6 +503,18 @@
           then builder <> separator <> element
           else element
     extract (Product2 _ builder) = builder
+
+-- | Intercalate projecting values to builder
+{-# INLINE intercalateMap #-}
+intercalateMap :: Foldable f => TextBuilder -> (a -> TextBuilder) -> f a -> TextBuilder
+intercalateMap separator mapper = extract . foldl' step init
+  where
+    init = Nothing
+    step acc element =
+      Just $ case acc of
+        Nothing -> mapper element
+        Just acc -> acc <> separator <> mapper element
+    extract = fromMaybe mempty
 
 -- | Pad a builder from the left side to the specified length with the specified character
 {-# INLINEABLE padFromLeft #-}
diff --git a/library/TextBuilderDev/UTF8.hs b/library/TextBuilderDev/UTF8.hs
--- a/library/TextBuilderDev/UTF8.hs
+++ b/library/TextBuilderDev/UTF8.hs
@@ -17,17 +17,17 @@
 unicodeCodePoint x case1 case2 case3 case4
   | x < 0x80 = case1 (fromIntegral x)
   | x < 0x800 =
-    case2
-      (fromIntegral $ x `shiftR` 6 .|. 0xC0)
-      (fromIntegral $ (x .&. 0x3F) .|. 0x80)
+      case2
+        (fromIntegral $ x `shiftR` 6 .|. 0xC0)
+        (fromIntegral $ (x .&. 0x3F) .|. 0x80)
   | x < 0x10000 =
-    case3
-      (fromIntegral $ x `shiftR` 12 .|. 0xE0)
-      (fromIntegral $ (x `shiftR` 6) .&. 0x3F .|. 0x80)
-      (fromIntegral $ (x .&. 0x3F) .|. 0x80)
+      case3
+        (fromIntegral $ x `shiftR` 12 .|. 0xE0)
+        (fromIntegral $ (x `shiftR` 6) .&. 0x3F .|. 0x80)
+        (fromIntegral $ (x .&. 0x3F) .|. 0x80)
   | otherwise =
-    case4
-      (fromIntegral $ x `shiftR` 18 .|. 0xF0)
-      (fromIntegral $ (x `shiftR` 12) .&. 0x3F .|. 0x80)
-      (fromIntegral $ (x `shiftR` 6) .&. 0x3F .|. 0x80)
-      (fromIntegral $ (x .&. 0x3F) .|. 0x80)
+      case4
+        (fromIntegral $ x `shiftR` 18 .|. 0xF0)
+        (fromIntegral $ (x `shiftR` 12) .&. 0x3F .|. 0x80)
+        (fromIntegral $ (x `shiftR` 6) .&. 0x3F .|. 0x80)
+        (fromIntegral $ (x .&. 0x3F) .|. 0x80)
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -28,6 +28,10 @@
           \separator texts ->
             Text.intercalate separator texts
               === B.buildText (B.intercalate (B.text separator) (fmap B.text texts)),
+        testProperty "intercalateMap sep mapper == intercalate sep . fmap mapper" $
+          \separator ints ->
+            Text.intercalate separator (fmap (fromString . show @Int) ints)
+              === B.buildText (B.intercalateMap (B.text separator) B.decimal ints),
         testProperty "Packing a list of chars is isomorphic to appending a list of builders" $
           \chars ->
             Text.pack chars
diff --git a/test/TextBuilderDev/TastyExtras.hs b/test/TextBuilderDev/TastyExtras.hs
--- a/test/TextBuilderDev/TastyExtras.hs
+++ b/test/TextBuilderDev/TastyExtras.hs
@@ -9,7 +9,7 @@
 import qualified TextBuilderDev as B
 import Prelude hiding (choose)
 
--- *
+-- * --
 
 instance Arbitrary TextLazyBuilder.Builder where
   arbitrary =
@@ -19,7 +19,7 @@
   arbitrary =
     B.lazyText <$> arbitrary
 
--- *
+-- * --
 
 isomorphismLaws ::
   (B.IsomorphicToTextBuilder a, Eq a, Show a, Arbitrary a) =>
diff --git a/text-builder-dev.cabal b/text-builder-dev.cabal
--- a/text-builder-dev.cabal
+++ b/text-builder-dev.cabal
@@ -1,7 +1,7 @@
 cabal-version: 3.0
 
 name: text-builder-dev
-version: 0.3.1
+version: 0.3.2
 category: Text
 synopsis: Edge of developments for "text-builder"
 description:
