diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2015, Nikita Volkov
+Copyright (c) 2017, Nikita Volkov
 
 Permission is hereby granted, free of charge, to any person
 obtaining a copy of this software and associated documentation
diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/benchmark-char/Main.hs b/benchmark-char/Main.hs
--- a/benchmark-char/Main.hs
+++ b/benchmark-char/Main.hs
@@ -1,33 +1,26 @@
 module Main where
 
-import Prelude
 import Criterion.Main
-import qualified Text.Builder as A
-import qualified Data.Text.Lazy.Builder as B
-import qualified Data.Text.Lazy as C
 import qualified Data.Text as D
-
+import qualified Data.Text.Lazy as C
+import qualified Data.Text.Lazy.Builder as B
+import qualified Text.Builder as A
+import Prelude
 
 main =
   defaultMain $
-  [
-    subjectBenchmark "builderSubject" builderSubject
-    ,
-    subjectBenchmark "lazyTextBuilderSubject" lazyTextBuilderSubject
-    ,
-    subjectBenchmark "plainTextPackingSubject" plainTextPackingSubject
-  ]
+    [ subjectBenchmark "builderSubject" builderSubject,
+      subjectBenchmark "lazyTextBuilderSubject" lazyTextBuilderSubject,
+      subjectBenchmark "plainTextPackingSubject" plainTextPackingSubject
+    ]
 
 subjectBenchmark :: String -> Subject -> Benchmark
 subjectBenchmark title subject =
   bgroup title $
-  [
-    benchmark "Small input" smallInput subject
-    ,
-    benchmark "Medium input" mediumInput subject
-    ,
-    benchmark "Large input" largeInput subject
-  ]
+    [ benchmark "Small input" smallInput subject,
+      benchmark "Medium input" mediumInput subject,
+      benchmark "Large input" largeInput subject
+    ]
 
 benchmark :: String -> [Int] -> Subject -> Benchmark
 benchmark title input subject =
@@ -62,4 +55,3 @@
 largeInput :: [Int]
 largeInput =
   mconcat (replicate 100000 smallInput)
-
diff --git a/benchmark-text/Main.hs b/benchmark-text/Main.hs
--- a/benchmark-text/Main.hs
+++ b/benchmark-text/Main.hs
@@ -1,36 +1,31 @@
 module Main where
 
-import Prelude
 import Criterion.Main
-import qualified Text.Builder as A
-import qualified Data.Text.Lazy.Builder as B
-import qualified Data.Text.Lazy as C
 import qualified Data.Text as D
-
+import qualified Data.Text.Lazy as C
+import qualified Data.Text.Lazy.Builder as B
+import qualified Text.Builder as A
+import Prelude
 
 main =
   defaultMain $
-  [
-    subjectBenchmark "builderSubject" builderSubject
-    ,
-    subjectBenchmark "lazyTextBuilderSubject" lazyTextBuilderSubject
-  ]
+    [ subjectBenchmark "builderSubject" builderSubject,
+      subjectBenchmark "lazyTextBuilderSubject" lazyTextBuilderSubject
+    ]
 
 subjectBenchmark :: String -> Subject -> Benchmark
 subjectBenchmark title subject =
   bgroup title $
-  [
-    benchmark "Small input" smallSample subject
-    ,
-    benchmark "Large input" largeSample subject
-  ]
+    [ benchmark "Small input" smallSample subject,
+      benchmark "Large input" largeSample subject
+    ]
 
 benchmark :: String -> Sample -> Subject -> Benchmark
 benchmark title sample subject =
   bench title $ nf sample $ subject
 
-data Subject =
-  forall a. Subject (Text -> a) (a -> a -> a) a (a -> Text)
+data Subject
+  = forall a. Subject (Text -> a) (a -> a -> a) a (a -> Text)
 
 type Sample =
   Subject -> Text
@@ -47,12 +42,12 @@
 smallSample :: Sample
 smallSample (Subject text (<>) mempty run) =
   run $
-  text "abcd" <> (text "ABCD" <> text "Фываолдж") <> text "漢"
+    text "abcd" <> (text "ABCD" <> text "Фываолдж") <> text "漢"
 
 {-# NOINLINE largeSample #-}
 largeSample :: Sample
 largeSample (Subject text (<>) mempty run) =
   run $
-  foldl' (<>) mempty $ replicate 100000 $
-  text "abcd" <> (text "ABCD" <> text "Фываолдж") <> text "漢"
-
+    foldl' (<>) mempty $
+      replicate 100000 $
+        text "abcd" <> (text "ABCD" <> text "Фываолдж") <> text "漢"
diff --git a/library/Text/Builder.hs b/library/Text/Builder.hs
--- a/library/Text/Builder.hs
+++ b/library/Text/Builder.hs
@@ -1,394 +1,269 @@
 module Text.Builder
-(
-  Builder,
-  -- * Accessors
-  run,
-  length,
-  null,
-  -- ** Output IO
-  putToStdOut,
-  putToStdErr,
-  putLnToStdOut,
-  putLnToStdErr,
-  -- * Constructors
-  -- ** Builder manipulators
-  intercalate,
-  padFromLeft,
-  padFromRight,
-  -- ** Textual
-  text,
-  string,
-  asciiByteString,
-  -- ** Character
-  char,
-  -- *** Low-level character
-  unicodeCodePoint,
-  utf16CodeUnits1,
-  utf16CodeUnits2,
-  utf8CodeUnits1,
-  utf8CodeUnits2,
-  utf8CodeUnits3,
-  utf8CodeUnits4,
-  -- ** Integers
-  -- *** Decimal
-  decimal,
-  unsignedDecimal,
-  thousandSeparatedDecimal,
-  thousandSeparatedUnsignedDecimal,
-  dataSizeInBytesInDecimal,
-  -- *** Binary
-  unsignedBinary,
-  unsignedPaddedBinary,
-  -- *** Hexadecimal
-  hexadecimal,
-  unsignedHexadecimal,
-  -- ** Digits
-  decimalDigit,
-  hexadecimalDigit,
-  -- ** Real
-  fixedDouble,
-  doublePercent,
-  -- ** Time
-  intervalInSeconds,
-)
-where
+  ( Builder,
 
-import Text.Builder.Prelude hiding (length, null, intercalate)
-import qualified Data.Text.Array as B
-import qualified Data.Text.Internal as C
-import qualified Data.Text.Encoding as E
-import qualified Data.Text.Encoding.Error as E
-import qualified Text.Builder.UTF16 as D
-import qualified Data.ByteString as ByteString
-import qualified DeferredFolds.Unfoldr as Unfoldr
-import qualified Data.Text as Text
-import qualified Data.Text.IO as Text
+    -- * Accessors
+    run,
+    length,
+    null,
 
+    -- ** Output IO
+    putToStdOut,
+    putToStdErr,
+    putLnToStdOut,
+    putLnToStdErr,
 
-newtype Action =
-  Action (forall s. B.MArray s -> Int -> ST s ())
+    -- * Constructors
 
-{-|
-Specification of how to efficiently construct strict 'Text'.
-Provides instances of 'Semigroup' and 'Monoid', which have complexity of /O(1)/.
--}
-data Builder =
-  Builder !Action !Int !Int
+    -- ** Builder manipulators
+    intercalate,
+    padFromLeft,
+    padFromRight,
 
-instance Monoid Builder where
-  {-# INLINE mempty #-}
-  mempty =
-    Builder (Action (\_ _ -> return ())) 0 0
-  {-# INLINABLE mappend #-}
-  mappend (Builder (Action action1) arraySize1 charsAmount1) (Builder (Action action2) arraySize2 charsAmount2) =
-    Builder action arraySize charsAmount
-    where
-      action =
-        Action $ \array offset -> do
-          action1 array offset
-          action2 array (offset + arraySize1)
-      arraySize =
-        arraySize1 + arraySize2
-      charsAmount =
-        charsAmount1 + charsAmount2
+    -- ** Textual
+    text,
+    string,
+    asciiByteString,
+    hexData,
 
-instance Semigroup Builder where
-  (<>) = mappend
+    -- ** Character
+    char,
 
-instance IsString Builder where
-  fromString = string
+    -- *** Low-level character
+    unicodeCodePoint,
+    utf16CodeUnits1,
+    utf16CodeUnits2,
+    utf8CodeUnits1,
+    utf8CodeUnits2,
+    utf8CodeUnits3,
+    utf8CodeUnits4,
 
-instance Show Builder where
-  show = Text.unpack . run
+    -- ** Integers
 
+    -- *** Decimal
+    decimal,
+    unsignedDecimal,
+    thousandSeparatedDecimal,
+    thousandSeparatedUnsignedDecimal,
+    dataSizeInBytesInDecimal,
 
--- * Accessors
--------------------------
+    -- *** Binary
+    unsignedBinary,
+    unsignedPaddedBinary,
 
-{-| Get the amount of characters -}
+    -- *** Hexadecimal
+    hexadecimal,
+    unsignedHexadecimal,
+
+    -- ** Digits
+    decimalDigit,
+    hexadecimalDigit,
+
+    -- ** Real
+    fixedDouble,
+    doublePercent,
+
+    -- ** Time
+    intervalInSeconds,
+  )
+where
+
+import BasePrelude hiding (intercalate, length, null)
+import Data.ByteString (ByteString)
+import Data.Text (Text)
+import qualified TextBuilderDev as Dev
+
+-- |
+-- Specification of how to efficiently construct strict 'Text'.
+-- Provides instances of 'Semigroup' and 'Monoid', which have complexity of /O(1)/.
+newtype Builder
+  = Builder Dev.TextBuilder
+  deriving (Show, IsString, Semigroup, Monoid)
+
+-- | Get the amount of characters
 {-# INLINE length #-}
 length :: Builder -> Int
-length (Builder _ _ x) = x
+length = coerce Dev.length
 
-{-| Check whether the builder is empty -}
+-- | Check whether the builder is empty
 {-# INLINE null #-}
 null :: Builder -> Bool
-null = (== 0) . length
+null = coerce Dev.null
 
-{-| Execute a builder producing a strict text -}
+-- | Execute a builder producing a strict text
 run :: Builder -> Text
-run (Builder (Action action) arraySize _) =
-  C.text array 0 arraySize
-  where
-    array =
-      runST $ do
-        array <- B.new arraySize
-        action array 0
-        B.unsafeFreeze array
+run = coerce Dev.buildText
 
 -- ** Output IO
--------------------------
 
-{-| Put builder, to stdout -}
+-- | Put builder, to stdout
 putToStdOut :: Builder -> IO ()
-putToStdOut = Text.hPutStr stdout . run
+putToStdOut = coerce Dev.putToStdOut
 
-{-| Put builder, to stderr -}
+-- | Put builder, to stderr
 putToStdErr :: Builder -> IO ()
-putToStdErr = Text.hPutStr stderr . run
+putToStdErr = coerce Dev.putToStdErr
 
-{-| Put builder, followed by a line, to stdout -}
+-- | Put builder, followed by a line, to stdout
 putLnToStdOut :: Builder -> IO ()
-putLnToStdOut = Text.hPutStrLn stdout . run
+putLnToStdOut = coerce Dev.putLnToStdOut
 
-{-| Put builder, followed by a line, to stderr -}
+-- | Put builder, followed by a line, to stderr
 putLnToStdErr :: Builder -> IO ()
-putLnToStdErr = Text.hPutStrLn stderr . run
-
+putLnToStdErr = coerce Dev.putLnToStdErr
 
 -- * Constructors
--------------------------
 
-{-| Unicode character -}
+-- | Unicode character
 {-# INLINE char #-}
 char :: Char -> Builder
-char x =
-  unicodeCodePoint (ord x)
+char = coerce Dev.char
 
-{-| Unicode code point-}
+-- | Unicode code point
 {-# INLINE unicodeCodePoint #-}
 unicodeCodePoint :: Int -> Builder
-unicodeCodePoint x =
-  D.unicodeCodePoint x utf16CodeUnits1 utf16CodeUnits2
+unicodeCodePoint = coerce Dev.unicodeCodePoint
 
-{-| Single code-unit UTF-16 character -}
-{-# INLINABLE utf16CodeUnits1 #-}
+-- | Single code-unit UTF-16 character
+{-# INLINEABLE utf16CodeUnits1 #-}
 utf16CodeUnits1 :: Word16 -> Builder
-utf16CodeUnits1 unit =
-  Builder action 1 1
-  where
-    action =
-      Action $ \array offset -> B.unsafeWrite array offset unit
+utf16CodeUnits1 = coerce Dev.utf16CodeUnits1
 
-{-| Double code-unit UTF-16 character -}
-{-# INLINABLE utf16CodeUnits2 #-}
+-- | Double code-unit UTF-16 character
+{-# INLINEABLE utf16CodeUnits2 #-}
 utf16CodeUnits2 :: Word16 -> Word16 -> Builder
-utf16CodeUnits2 unit1 unit2 =
-  Builder action 2 1
-  where
-    action =
-      Action $ \array offset -> do
-        B.unsafeWrite array offset unit1
-        B.unsafeWrite array (succ offset) unit2
+utf16CodeUnits2 = coerce Dev.utf16CodeUnits2
 
-{-| Single code-unit UTF-8 character -}
+-- | Single code-unit UTF-8 character
 {-# INLINE utf8CodeUnits1 #-}
 utf8CodeUnits1 :: Word8 -> Builder
-utf8CodeUnits1 unit1 =
-  D.utf8CodeUnits1 unit1 utf16CodeUnits1 utf16CodeUnits2
+utf8CodeUnits1 = coerce Dev.utf8CodeUnits1
 
-{-| Double code-unit UTF-8 character -}
+-- | Double code-unit UTF-8 character
 {-# INLINE utf8CodeUnits2 #-}
 utf8CodeUnits2 :: Word8 -> Word8 -> Builder
-utf8CodeUnits2 unit1 unit2 =
-  D.utf8CodeUnits2 unit1 unit2 utf16CodeUnits1 utf16CodeUnits2
+utf8CodeUnits2 = coerce Dev.utf8CodeUnits2
 
-{-| Triple code-unit UTF-8 character -}
+-- | Triple code-unit UTF-8 character
 {-# INLINE utf8CodeUnits3 #-}
 utf8CodeUnits3 :: Word8 -> Word8 -> Word8 -> Builder
-utf8CodeUnits3 unit1 unit2 unit3 =
-  D.utf8CodeUnits3 unit1 unit2 unit3 utf16CodeUnits1 utf16CodeUnits2
+utf8CodeUnits3 = coerce Dev.utf8CodeUnits3
 
-{-| UTF-8 character out of 4 code units -}
+-- | UTF-8 character out of 4 code units
 {-# INLINE utf8CodeUnits4 #-}
 utf8CodeUnits4 :: Word8 -> Word8 -> Word8 -> Word8 -> Builder
-utf8CodeUnits4 unit1 unit2 unit3 unit4 =
-  D.utf8CodeUnits4 unit1 unit2 unit3 unit4 utf16CodeUnits1 utf16CodeUnits2
+utf8CodeUnits4 = coerce Dev.utf8CodeUnits4
 
-{-| ASCII byte string -}
-{-# INLINABLE asciiByteString #-}
+-- | ASCII byte string
+{-# INLINEABLE asciiByteString #-}
 asciiByteString :: ByteString -> Builder
-asciiByteString byteString =
-  Builder action length length
-  where
-    length = ByteString.length byteString
-    action =
-      Action $ \array -> let
-        step byte next index = do
-          B.unsafeWrite array index (fromIntegral byte)
-          next (succ index)
-        in ByteString.foldr step (const (return ())) byteString
+asciiByteString = coerce Dev.asciiByteString
 
-{-| Strict text -}
-{-# INLINABLE text #-}
+-- | Strict text
+{-# INLINEABLE text #-}
 text :: Text -> Builder
-text text@(C.Text array offset length) =
-  Builder action length (Text.length text)
-  where
-    action =
-      Action $ \builderArray builderOffset -> do
-        B.copyI builderArray builderOffset array offset (builderOffset + length)
+text = coerce Dev.text
 
-{-| String -}
+-- | String
 {-# INLINE string #-}
 string :: String -> Builder
-string =
-  foldMap char
+string = coerce Dev.string
 
-{-| Decimal representation of an integral value -}
-{-# INLINABLE decimal #-}
+-- | Decimal representation of an integral value
+{-# INLINEABLE decimal #-}
 decimal :: Integral a => a -> Builder
-decimal i =
-  if i >= 0
-    then unsignedDecimal i
-    else unicodeCodePoint 45 <> unsignedDecimal (negate i)
+decimal = coerce . Dev.decimal
 
-{-| Decimal representation of an unsigned integral value -}
-{-# INLINABLE unsignedDecimal #-}
+-- | Decimal representation of an unsigned integral value
+{-# INLINEABLE unsignedDecimal #-}
 unsignedDecimal :: Integral a => a -> Builder
-unsignedDecimal =
-  foldMap decimalDigit . Unfoldr.decimalDigits
+unsignedDecimal = coerce . Dev.unsignedDecimal
 
-{-| Decimal representation of an integral value with thousands separated by the specified character -}
-{-# INLINABLE thousandSeparatedDecimal #-}
+-- | Decimal representation of an integral value with thousands separated by the specified character
+{-# INLINEABLE thousandSeparatedDecimal #-}
 thousandSeparatedDecimal :: Integral a => Char -> a -> Builder
-thousandSeparatedDecimal separatorChar a =
-  if a >= 0
-    then thousandSeparatedUnsignedDecimal separatorChar a
-    else unicodeCodePoint 45 <> thousandSeparatedUnsignedDecimal separatorChar (negate a)
+thousandSeparatedDecimal = fmap coerce . Dev.thousandSeparatedDecimal
 
-{-| Decimal representation of an unsigned integral value with thousands separated by the specified character -}
-{-# INLINABLE thousandSeparatedUnsignedDecimal #-}
+-- | Decimal representation of an unsigned integral value with thousands separated by the specified character
+{-# INLINEABLE thousandSeparatedUnsignedDecimal #-}
 thousandSeparatedUnsignedDecimal :: Integral a => Char -> a -> Builder
-thousandSeparatedUnsignedDecimal separatorChar a =
-  fold $ do
-    (index, digit) <- Unfoldr.zipWithReverseIndex $ Unfoldr.decimalDigits a
-    if mod index 3 == 0 && index /= 0
-      then return (decimalDigit digit <> char separatorChar)
-      else return (decimalDigit digit)
+thousandSeparatedUnsignedDecimal = fmap coerce . Dev.thousandSeparatedUnsignedDecimal
 
-{-| Data size in decimal notation over amount of bytes. -}
-{-# INLINABLE dataSizeInBytesInDecimal #-}
+-- | Data size in decimal notation over amount of bytes.
+{-# INLINEABLE dataSizeInBytesInDecimal #-}
 dataSizeInBytesInDecimal :: Integral a => Char -> a -> Builder
-dataSizeInBytesInDecimal separatorChar amount =
-  if amount < 1000
-    then unsignedDecimal amount <> "B"
-    else if amount < 1000000
-      then dividedDecimal separatorChar 100 amount <> "kB"
-      else if amount < 1000000000
-        then dividedDecimal separatorChar 100000 amount <> "MB"
-        else if amount < 1000000000000
-          then dividedDecimal separatorChar 100000000 amount <> "GB"
-        else if amount < 1000000000000000
-          then dividedDecimal separatorChar 100000000000 amount <> "TB"
-        else if amount < 1000000000000000000
-          then dividedDecimal separatorChar 100000000000000 amount <> "PB"
-        else if amount < 1000000000000000000000
-          then dividedDecimal separatorChar 100000000000000000 amount <> "EB"
-          else if amount < 1000000000000000000000000
-            then dividedDecimal separatorChar 100000000000000000000 amount <> "ZB"
-            else dividedDecimal separatorChar 100000000000000000000000 amount <> "YB"
-
-dividedDecimal :: Integral a => Char -> a -> a -> Builder
-dividedDecimal separatorChar divisor n = let
-  byDivisor = div n divisor
-  byExtraTen = div byDivisor 10
-  remainder = byDivisor - byExtraTen * 10
-  in if remainder == 0 || byExtraTen >= 10
-    then thousandSeparatedDecimal separatorChar byExtraTen
-    else thousandSeparatedDecimal separatorChar byExtraTen <> "." <> decimalDigit remainder
+dataSizeInBytesInDecimal = fmap coerce . Dev.dataSizeInBytesInDecimal
 
-{-| Unsigned binary number -}
+-- | Unsigned binary number
 {-# INLINE unsignedBinary #-}
 unsignedBinary :: Integral a => a -> Builder
-unsignedBinary =
-  foldMap decimalDigit . Unfoldr.binaryDigits
+unsignedBinary = coerce . Dev.unsignedBinary
 
-{-| Unsigned binary number -}
+-- | Unsigned binary number
 {-# INLINE unsignedPaddedBinary #-}
 unsignedPaddedBinary :: (Integral a, FiniteBits a) => a -> Builder
-unsignedPaddedBinary a =
-  padFromLeft (finiteBitSize a) '0' $ foldMap decimalDigit $ Unfoldr.binaryDigits a
+unsignedPaddedBinary = coerce . Dev.unsignedPaddedBinary
 
-{-| Hexadecimal representation of an integral value -}
+-- | Hexadecimal representation of an integral value
 {-# INLINE hexadecimal #-}
 hexadecimal :: Integral a => a -> Builder
-hexadecimal i =
-  if i >= 0
-    then unsignedHexadecimal i
-    else unicodeCodePoint 45 <> unsignedHexadecimal (negate i)
+hexadecimal = coerce . Dev.hexadecimal
 
-{-| Unsigned hexadecimal representation of an integral value -}
+-- | Unsigned hexadecimal representation of an integral value
 {-# INLINE unsignedHexadecimal #-}
 unsignedHexadecimal :: Integral a => a -> Builder
-unsignedHexadecimal =
-  foldMap hexadecimalDigit . Unfoldr.hexadecimalDigits
+unsignedHexadecimal = coerce . Dev.unsignedHexadecimal
 
-{-| Decimal digit -}
+-- | Decimal digit
 {-# INLINE decimalDigit #-}
 decimalDigit :: Integral a => a -> Builder
-decimalDigit n =
-  unicodeCodePoint (fromIntegral n + 48)
+decimalDigit = coerce . Dev.decimalDigit
 
-{-| Hexadecimal digit -}
+-- | Hexadecimal digit
 {-# INLINE hexadecimalDigit #-}
 hexadecimalDigit :: Integral a => a -> Builder
-hexadecimalDigit n =
-  if n <= 9
-    then unicodeCodePoint (fromIntegral n + 48)
-    else unicodeCodePoint (fromIntegral n + 87)
+hexadecimalDigit = coerce . Dev.hexadecimalDigit
 
-{-| Intercalate builders -}
+-- | Intercalate builders
 {-# INLINE intercalate #-}
 intercalate :: Foldable foldable => Builder -> foldable Builder -> Builder
-intercalate separator = extract . foldl' step init where
-  init = Product2 False mempty
-  step (Product2 isNotFirst builder) element = Product2 True $ if isNotFirst
-    then builder <> separator <> element
-    else element
-  extract (Product2 _ builder) = builder
+intercalate a b = coerce (Dev.intercalate (coerce a) (foldr ((:) . coerce) [] b))
 
-{-| Pad a builder from the left side to the specified length with the specified character -}
-{-# INLINABLE padFromLeft #-}
+-- | Pad a builder from the left side to the specified length with the specified character
+{-# INLINEABLE padFromLeft #-}
 padFromLeft :: Int -> Char -> Builder -> Builder
-padFromLeft paddedLength paddingChar builder = let
-  builderLength = length builder
-  in if paddedLength <= builderLength
-    then builder
-    else foldMap char (replicate (paddedLength - builderLength) paddingChar) <> builder
+padFromLeft = coerce Dev.padFromLeft
 
-{-| Pad a builder from the right side to the specified length with the specified character -}
-{-# INLINABLE padFromRight #-}
+-- | Pad a builder from the right side to the specified length with the specified character
+{-# INLINEABLE padFromRight #-}
 padFromRight :: Int -> Char -> Builder -> Builder
-padFromRight paddedLength paddingChar builder = let
-  builderLength = length builder
-  in if paddedLength <= builderLength
-    then builder
-    else builder <> foldMap char (replicate (paddedLength - builderLength) paddingChar)
+padFromRight = coerce Dev.padFromRight
 
-{-|
-Time interval in seconds.
-Directly applicable to 'DiffTime' and 'NominalDiffTime'.
--}
-{-# INLINABLE intervalInSeconds #-}
+-- |
+-- Time interval in seconds.
+-- Directly applicable to 'DiffTime' and 'NominalDiffTime'.
+{-# INLINEABLE intervalInSeconds #-}
 intervalInSeconds :: RealFrac seconds => seconds -> Builder
-intervalInSeconds interval = flip evalState (round interval) $ do
-  seconds <- state (swap . flip divMod 60)
-  minutes <- state (swap . flip divMod 60)
-  hours <- state (swap . flip divMod 24)
-  days <- get
-  return $
-    padFromLeft 2 '0' (decimal days) <> ":" <>
-    padFromLeft 2 '0' (decimal hours) <> ":" <>
-    padFromLeft 2 '0' (decimal minutes) <> ":" <>
-    padFromLeft 2 '0' (decimal seconds)
+intervalInSeconds = coerce . Dev.intervalInSeconds
 
-{-| Double with a fixed number of decimal places. -}
+-- | Double with a fixed number of decimal places.
 {-# INLINE fixedDouble #-}
-fixedDouble :: Int {-^ Amount of decimals after point. -} -> Double -> Builder
-fixedDouble decimalPlaces = fromString . printf ("%." ++ show decimalPlaces ++ "f")
+fixedDouble ::
+  -- | Amount of decimals after point.
+  Int ->
+  Double ->
+  Builder
+fixedDouble = coerce Dev.fixedDouble
 
-{-| Double multiplied by 100 with a fixed number of decimal places applied and followed by a percent-sign. -}
+-- | Double multiplied by 100 with a fixed number of decimal places applied and followed by a percent-sign.
 {-# INLINE doublePercent #-}
-doublePercent :: Int {-^ Amount of decimals after point. -} -> Double -> Builder
-doublePercent decimalPlaces x = fixedDouble decimalPlaces (x * 100) <> "%"
+doublePercent ::
+  -- | Amount of decimals after point.
+  Int ->
+  Double ->
+  Builder
+doublePercent = coerce Dev.doublePercent
+
+-- | Hexadecimal readable representation of binary data.
+{-# INLINE hexData #-}
+hexData :: ByteString -> Builder
+hexData = coerce Dev.hexData
diff --git a/library/Text/Builder/Prelude.hs b/library/Text/Builder/Prelude.hs
deleted file mode 100644
--- a/library/Text/Builder/Prelude.hs
+++ /dev/null
@@ -1,97 +0,0 @@
-module Text.Builder.Prelude
-( 
-  module Exports,
-  Product2(..),
-)
-where
-
--- base
--------------------------
-import Control.Applicative as Exports
-import Control.Arrow as Exports
-import Control.Category as Exports
-import Control.Concurrent as Exports
-import Control.Exception as Exports
-import Control.Monad as Exports hiding (mapM_, sequence_, forM_, msum, mapM, sequence, forM)
-import Control.Monad.IO.Class as Exports
-import Control.Monad.Fix as Exports hiding (fix)
-import Control.Monad.ST as Exports
-import Control.Monad.ST.Unsafe as Exports
-import Data.Bits as Exports
-import Data.Bool as Exports
-import Data.Char as Exports
-import Data.Coerce as Exports
-import Data.Complex as Exports
-import Data.Data as Exports
-import Data.Dynamic as Exports
-import Data.Either as Exports
-import Data.Fixed as Exports
-import Data.Foldable as Exports
-import Data.Function as Exports hiding (id, (.))
-import Data.Functor as Exports
-import Data.Functor.Identity as Exports
-import Data.Int as Exports
-import Data.IORef as Exports
-import Data.Ix as Exports
-import Data.List as Exports hiding (sortOn, isSubsequenceOf, uncons, concat, foldr, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, find, maximumBy, minimumBy, mapAccumL, mapAccumR, foldl')
-import Data.Maybe as Exports
-import Data.Monoid as Exports hiding (Last(..), First(..), (<>))
-import Data.Ord as Exports
-import Data.Proxy as Exports
-import Data.Ratio as Exports
-import Data.Semigroup as Exports
-import Data.STRef as Exports
-import Data.String as Exports
-import Data.Traversable as Exports
-import Data.Tuple as Exports
-import Data.Unique as Exports
-import Data.Version as Exports
-import Data.Word as Exports
-import Debug.Trace as Exports
-import Foreign.ForeignPtr.Unsafe as Exports
-import Foreign.ForeignPtr as Exports
-import Foreign.Ptr as Exports
-import Foreign.StablePtr as Exports
-import Foreign.Storable as Exports hiding (sizeOf, alignment)
-import GHC.Conc as Exports hiding (withMVar, threadWaitWriteSTM, threadWaitWrite, threadWaitReadSTM, threadWaitRead)
-import GHC.Exts as Exports (lazy, inline, sortWith, groupWith)
-import GHC.Generics as Exports (Generic)
-import GHC.IO.Exception as Exports
-import Numeric as Exports
-import Prelude as Exports hiding (concat, foldr, mapM_, sequence_, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, mapM, sequence, id, (.))
-import System.Environment as Exports
-import System.Exit as Exports
-import System.IO as Exports
-import System.IO.Error as Exports
-import System.IO.Unsafe as Exports
-import System.Mem as Exports
-import System.Mem.StableName as Exports
-import System.Timeout as Exports
-import Text.ParserCombinators.ReadP as Exports (ReadP, ReadS, readP_to_S, readS_to_P)
-import Text.ParserCombinators.ReadPrec as Exports (ReadPrec, readPrec_to_P, readP_to_Prec, readPrec_to_S, readS_to_Prec)
-import Text.Printf as Exports (printf, hPrintf)
-import Text.Read as Exports (Read(..), readMaybe, readEither)
-import Unsafe.Coerce as Exports
-
--- bytestring
--------------------------
-import Data.ByteString as Exports (ByteString)
-
--- text
--------------------------
-import Data.Text as Exports (Text)
-
--- deferred-folds
--------------------------
-import DeferredFolds.Unfoldr as Exports (Unfoldr(..))
-
--- transformers
--------------------------
-import Control.Monad.IO.Class as Exports
-import Control.Monad.Trans.Class as Exports
-import Control.Monad.Trans.Maybe as Exports hiding (liftListen, liftPass)
-import Control.Monad.Trans.Reader as Exports hiding (liftCallCC, liftCatch)
-import Control.Monad.Trans.State.Strict as Exports hiding (liftCallCC, liftCatch, liftListen, liftPass)
-
-
-data Product2 a b = Product2 !a !b
diff --git a/library/Text/Builder/UTF16.hs b/library/Text/Builder/UTF16.hs
deleted file mode 100644
--- a/library/Text/Builder/UTF16.hs
+++ /dev/null
@@ -1,61 +0,0 @@
-module Text.Builder.UTF16
-where
-
-import Text.Builder.Prelude
-
-
-{-|
-A matching function, which chooses the continuation to run.
--}
-type UTF16View =
-  forall x. (Word16 -> x) -> (Word16 -> Word16 -> x) -> x
-
-{-# INLINE char #-}
-char :: Char -> UTF16View
-char x =
-  unicodeCodePoint (ord x)
-
-{-# INLINE unicodeCodePoint #-}
-unicodeCodePoint :: Int -> UTF16View
-unicodeCodePoint x case1 case2 =
-  if x < 0x10000
-    then case1 (fromIntegral x)
-    else case2 case2Unit1 case2Unit2
-  where
-    m =
-      x - 0x10000
-    case2Unit1 =
-      fromIntegral (shiftR m 10 + 0xD800)
-    case2Unit2 =
-      fromIntegral ((m .&. 0x3FF) + 0xDC00)
-
-{-# INLINE utf8CodeUnits1 #-}
-utf8CodeUnits1 :: Word8 -> UTF16View
-utf8CodeUnits1 x case1 _ =
-  case1 (fromIntegral x)
-
-{-# INLINE utf8CodeUnits2 #-}
-utf8CodeUnits2 :: Word8 -> Word8 -> UTF16View
-utf8CodeUnits2 byte1 byte2 case1 _ =
-  case1 (shiftL (fromIntegral byte1 - 0xC0) 6 + fromIntegral byte2 - 0x80)
-
-{-# INLINE utf8CodeUnits3 #-}
-utf8CodeUnits3 :: Word8 -> Word8 -> Word8 -> UTF16View
-utf8CodeUnits3 byte1 byte2 byte3 case1 case2 =
-  unicodeCodePoint unicode case1 case2
-  where
-    unicode =
-      shiftL (fromIntegral byte1 - 0xE0) 12 +
-      shiftL (fromIntegral byte2 - 0x80) 6 +
-      fromIntegral byte3 - 0x80
-
-{-# INLINE utf8CodeUnits4 #-}
-utf8CodeUnits4 :: Word8 -> Word8 -> Word8 -> Word8 -> UTF16View
-utf8CodeUnits4 byte1 byte2 byte3 byte4 case1 case2 =
-  unicodeCodePoint unicode case1 case2
-  where
-    unicode =
-      shiftL (fromIntegral byte1 - 0xE0) 18 +
-      shiftL (fromIntegral byte2 - 0x80) 12 +
-      shiftL (fromIntegral byte3 - 0x80) 6 +
-      fromIntegral byte4 - 0x80
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -1,104 +1,86 @@
 module Main where
 
-import Prelude hiding (choose)
+import qualified Data.ByteString as ByteString
+import qualified Data.Text as A
+import qualified Data.Text.Encoding as Text
 import Test.QuickCheck.Instances
 import Test.Tasty
 import Test.Tasty.HUnit
 import Test.Tasty.QuickCheck
-import qualified Data.Text as A
 import qualified Text.Builder as B
-import qualified Data.ByteString as ByteString
-import qualified Data.Text.Encoding as Text
-
+import Prelude hiding (choose)
 
 main =
   defaultMain $
-  testGroup "All tests" $
-  [
-    testProperty "ASCII ByteString" $ let
-      gen = listOf $ do
-        list <- listOf (choose (0, 127))
-        return (ByteString.pack list)
-      in forAll gen $ \ chunks ->
-        mconcat chunks ===
-        Text.encodeUtf8 (B.run (foldMap B.asciiByteString chunks))
-    ,
-    testProperty "Intercalation has the same effect as in Text" $
-    \ separator texts ->
-      A.intercalate separator texts ===
-      B.run (B.intercalate (B.text separator) (fmap B.text texts))
-    ,
-    testProperty "Packing a list of chars is isomorphic to appending a list of builders" $
-    \ chars ->
-      A.pack chars ===
-      B.run (foldMap B.char chars)
-    ,
-    testProperty "Concatting a list of texts is isomorphic to fold-mapping with builders" $
-    \ texts ->
-      mconcat texts ===
-      B.run (foldMap B.text texts)
-    ,
-    testProperty "Concatting a list of texts is isomorphic to concatting a list of builders" $
-    \ texts ->
-      mconcat texts ===
-      B.run (mconcat (map B.text texts))
-    ,
-    testProperty "Concatting a list of trimmed texts is isomorphic to concatting a list of builders" $
-    \ texts ->
-      let
-        trimmedTexts = fmap (A.drop 3) texts
-        in
-          mconcat trimmedTexts ===
-          B.run (mconcat (map B.text trimmedTexts))
-    ,
-    testProperty "Decimal" $ \ (x :: Integer) ->
-    (fromString . show) x === (B.run (B.decimal x))
-    ,
-    testProperty "Hexadecimal vs std show" $ \ (x :: Integer) -> x >= 0 ==>
-    (fromString . showHex x) "" === (B.run . B.hexadecimal) x
-    ,
-    testCase "Separated thousands" $ do
-      assertEqual "" "0" (B.run (B.thousandSeparatedUnsignedDecimal ',' 0))
-      assertEqual "" "123" (B.run (B.thousandSeparatedUnsignedDecimal ',' 123))
-      assertEqual "" "1,234" (B.run (B.thousandSeparatedUnsignedDecimal ',' 1234))
-      assertEqual "" "1,234,567" (B.run (B.thousandSeparatedUnsignedDecimal ',' 1234567))
-    ,
-    testCase "Pad from left" $ do
-      assertEqual "" "00" (B.run (B.padFromLeft 2 '0' ""))
-      assertEqual "" "00" (B.run (B.padFromLeft 2 '0' "0"))
-      assertEqual "" "01" (B.run (B.padFromLeft 2 '0' "1"))
-      assertEqual "" "12" (B.run (B.padFromLeft 2 '0' "12"))
-      assertEqual "" "123" (B.run (B.padFromLeft 2 '0' "123"))
-    ,
-    testCase "Pad from right" $ do
-      assertEqual "" "00" (B.run (B.padFromRight 2 '0' ""))
-      assertEqual "" "00" (B.run (B.padFromRight 2 '0' "0"))
-      assertEqual "" "10" (B.run (B.padFromRight 2 '0' "1"))
-      assertEqual "" "12" (B.run (B.padFromRight 2 '0' "12"))
-      assertEqual "" "123" (B.run (B.padFromRight 2 '0' "123"))
-      assertEqual "" "1  " (B.run (B.padFromRight 3 ' ' "1"))
-    ,
-    testCase "Hexadecimal" $
-    assertEqual "" "1f23" (B.run (B.hexadecimal 0x01f23))
-    ,
-    testCase "Negative Hexadecimal" $
-    assertEqual "" "-1f23" (B.run (B.hexadecimal (-0x01f23)))
-    ,
-    testGroup "Time interval" $
-    [
-      testCase "59s" $ assertEqual "" "00:00:00:59" $ B.run $ B.intervalInSeconds 59,
-      testCase "minute" $ assertEqual "" "00:00:01:00" $ B.run $ B.intervalInSeconds 60,
-      testCase "90s" $ assertEqual "" "00:00:01:30" $ B.run $ B.intervalInSeconds 90,
-      testCase "hour" $ assertEqual "" "00:01:00:00" $ B.run $ B.intervalInSeconds 3600,
-      testCase "day" $ assertEqual "" "01:00:00:00" $ B.run $ B.intervalInSeconds 86400
-    ]
-    ,
-    testCase "dataSizeInBytesInDecimal" $ do
-      assertEqual "" "999B" (B.run (B.dataSizeInBytesInDecimal ',' 999))
-      assertEqual "" "1kB" (B.run (B.dataSizeInBytesInDecimal ',' 1000))
-      assertEqual "" "1.1kB" (B.run (B.dataSizeInBytesInDecimal ',' 1100))
-      assertEqual "" "1.1MB" (B.run (B.dataSizeInBytesInDecimal ',' 1150000))
-      assertEqual "" "9.9MB" (B.run (B.dataSizeInBytesInDecimal ',' 9990000))
-      assertEqual "" "10MB" (B.run (B.dataSizeInBytesInDecimal ',' 10100000))
-      assertEqual "" "1,000YB" (B.run (B.dataSizeInBytesInDecimal ',' 1000000000000000000000000000))
-  ]
+    testGroup "All tests" $
+      [ testProperty "ASCII ByteString" $
+          let gen = listOf $ do
+                list <- listOf (choose (0, 127))
+                return (ByteString.pack list)
+           in forAll gen $ \chunks ->
+                mconcat chunks
+                  === Text.encodeUtf8 (B.run (foldMap B.asciiByteString chunks)),
+        testProperty "Intercalation has the same effect as in Text" $
+          \separator texts ->
+            A.intercalate separator texts
+              === B.run (B.intercalate (B.text separator) (fmap B.text texts)),
+        testProperty "Packing a list of chars is isomorphic to appending a list of builders" $
+          \chars ->
+            A.pack chars
+              === B.run (foldMap B.char chars),
+        testProperty "Concatting a list of texts is isomorphic to fold-mapping with builders" $
+          \texts ->
+            mconcat texts
+              === B.run (foldMap B.text texts),
+        testProperty "Concatting a list of texts is isomorphic to concatting a list of builders" $
+          \texts ->
+            mconcat texts
+              === B.run (mconcat (map B.text texts)),
+        testProperty "Concatting a list of trimmed texts is isomorphic to concatting a list of builders" $
+          \texts ->
+            let trimmedTexts = fmap (A.drop 3) texts
+             in mconcat trimmedTexts
+                  === B.run (mconcat (map B.text trimmedTexts)),
+        testProperty "Decimal" $ \(x :: Integer) ->
+          (fromString . show) x === (B.run (B.decimal x)),
+        testProperty "Hexadecimal vs std show" $ \(x :: Integer) ->
+          x >= 0
+            ==> (fromString . showHex x) "" === (B.run . B.hexadecimal) x,
+        testCase "Separated thousands" $ do
+          assertEqual "" "0" (B.run (B.thousandSeparatedUnsignedDecimal ',' 0))
+          assertEqual "" "123" (B.run (B.thousandSeparatedUnsignedDecimal ',' 123))
+          assertEqual "" "1,234" (B.run (B.thousandSeparatedUnsignedDecimal ',' 1234))
+          assertEqual "" "1,234,567" (B.run (B.thousandSeparatedUnsignedDecimal ',' 1234567)),
+        testCase "Pad from left" $ do
+          assertEqual "" "00" (B.run (B.padFromLeft 2 '0' ""))
+          assertEqual "" "00" (B.run (B.padFromLeft 2 '0' "0"))
+          assertEqual "" "01" (B.run (B.padFromLeft 2 '0' "1"))
+          assertEqual "" "12" (B.run (B.padFromLeft 2 '0' "12"))
+          assertEqual "" "123" (B.run (B.padFromLeft 2 '0' "123")),
+        testCase "Pad from right" $ do
+          assertEqual "" "00" (B.run (B.padFromRight 2 '0' ""))
+          assertEqual "" "00" (B.run (B.padFromRight 2 '0' "0"))
+          assertEqual "" "10" (B.run (B.padFromRight 2 '0' "1"))
+          assertEqual "" "12" (B.run (B.padFromRight 2 '0' "12"))
+          assertEqual "" "123" (B.run (B.padFromRight 2 '0' "123"))
+          assertEqual "" "1  " (B.run (B.padFromRight 3 ' ' "1")),
+        testCase "Hexadecimal" $
+          assertEqual "" "1f23" (B.run (B.hexadecimal 0x01f23)),
+        testCase "Negative Hexadecimal" $
+          assertEqual "" "-1f23" (B.run (B.hexadecimal (-0x01f23))),
+        testGroup "Time interval" $
+          [ testCase "59s" $ assertEqual "" "00:00:00:59" $ B.run $ B.intervalInSeconds 59,
+            testCase "minute" $ assertEqual "" "00:00:01:00" $ B.run $ B.intervalInSeconds 60,
+            testCase "90s" $ assertEqual "" "00:00:01:30" $ B.run $ B.intervalInSeconds 90,
+            testCase "hour" $ assertEqual "" "00:01:00:00" $ B.run $ B.intervalInSeconds 3600,
+            testCase "day" $ assertEqual "" "01:00:00:00" $ B.run $ B.intervalInSeconds 86400
+          ],
+        testCase "dataSizeInBytesInDecimal" $ do
+          assertEqual "" "999B" (B.run (B.dataSizeInBytesInDecimal ',' 999))
+          assertEqual "" "1kB" (B.run (B.dataSizeInBytesInDecimal ',' 1000))
+          assertEqual "" "1.1kB" (B.run (B.dataSizeInBytesInDecimal ',' 1100))
+          assertEqual "" "1.1MB" (B.run (B.dataSizeInBytesInDecimal ',' 1150000))
+          assertEqual "" "9.9MB" (B.run (B.dataSizeInBytesInDecimal ',' 9990000))
+          assertEqual "" "10MB" (B.run (B.dataSizeInBytesInDecimal ',' 10100000))
+          assertEqual "" "1,000YB" (B.run (B.dataSizeInBytesInDecimal ',' 1000000000000000000000000000))
+      ]
diff --git a/text-builder.cabal b/text-builder.cabal
--- a/text-builder.cabal
+++ b/text-builder.cabal
@@ -1,5 +1,7 @@
+cabal-version: 3.0
+
 name: text-builder
-version: 0.6.6.3
+version: 0.6.6.4
 category: Text
 synopsis: An efficient strict text builder
 homepage: https://github.com/nikita-volkov/text-builder
@@ -9,30 +11,30 @@
 copyright: (c) 2017, Nikita Volkov
 license: MIT
 license-file: LICENSE
-build-type: Simple
-cabal-version: >=1.10
 
+source-repository head
+  type: git
+  location: git://github.com/nikita-volkov/text-builder.git
+
+common language-settings
+  default-extensions: BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples
+  default-language: Haskell2010
+
 library
+  import: language-settings
   hs-source-dirs: library
-  default-extensions: Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples
-  default-language: Haskell2010
   exposed-modules:
     Text.Builder
-  other-modules:
-    Text.Builder.UTF16
-    Text.Builder.Prelude
   build-depends:
-    base >=4.10 && <5,
+    base-prelude >=1.6 && <2,
     bytestring >=0.10 && <0.12,
-    deferred-folds >=0.9.10.1 && <0.10,
-    text >=1 && <2,
-    transformers >=0.5 && <0.6
+    text >=1.2 && <3,
+    text-builder-dev >=0.2 && <0.3,
 
 test-suite test
+  import: language-settings
   type: exitcode-stdio-1.0
   hs-source-dirs: test
-  default-extensions: Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples
-  default-language: Haskell2010
   main-is: Main.hs
   build-depends:
     QuickCheck >=2.13 && <3,
@@ -41,28 +43,26 @@
     tasty >=1.2.3 && <2,
     tasty-hunit >=0.10.0.2 && <0.11,
     tasty-quickcheck >=0.10.1 && <0.11,
-    text-builder
+    text-builder,
 
 benchmark benchmark-text
+  import: language-settings
   type: exitcode-stdio-1.0
   hs-source-dirs: benchmark-text
-  default-extensions: Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveTraversable, DeriveGeneric, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples
-  default-language: Haskell2010
   ghc-options: -O2 -threaded "-with-rtsopts=-N" -funbox-strict-fields
   main-is: Main.hs
   build-depends:
     criterion >=1.5.6.1 && <2,
     rerebase ==1.*,
-    text-builder
+    text-builder,
 
 benchmark benchmark-char
+  import: language-settings
   type: exitcode-stdio-1.0
   hs-source-dirs: benchmark-char
-  default-extensions: Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveTraversable, DeriveGeneric, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples
-  default-language: Haskell2010
   ghc-options: -O2 -threaded "-with-rtsopts=-N" -funbox-strict-fields
   main-is: Main.hs
   build-depends:
     criterion >=1.5.6.1 && <2,
     rerebase ==1.*,
-    text-builder
+    text-builder,
