diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2014 Ivan Lazar Miljenovic
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/buildable.cabal b/buildable.cabal
new file mode 100644
--- /dev/null
+++ b/buildable.cabal
@@ -0,0 +1,55 @@
+name:                buildable
+version:             0.1.0.0
+synopsis:            Typeclass for builders of linear data structures
+description: {
+Various linear data structures can be expensive to construct in a
+repetitive fashion.  For example, to append a single value to the end
+of a list is @O(n)@, and as such doing so repeatedly is recommended
+against.
+.
+As such, to efficiently construct such structures we have the notion
+of a /builder/.  This can be used to more efficiently prepend and
+append values, and at the end we \"run\" the builder to construct the
+overall value.
+.
+This module provides an abstraction over various builders for specific
+data structures.  It also aims to minimise the number of functions
+required to add various values to the builder by using a typeclass and
+newtype wrappers.
+.
+To construct a value from it's builder:
+.
+    1. Start with either @'mempty'@ for an empty 'Builder', or if you
+       have an initial value use @'fromValue'@.
+.
+    2. Add initial values to the front or back using 'prepend' \/ '<|'
+       or 'append' \/ '|>' respectively.
+.
+    3. Once you've finished constructing your builder, create your
+       final value with 'build'.
+.
+/Note/: all instances are defined for both strict and lazy
+@ByteString@ and @Text@ values.
+}
+
+license:             MIT
+license-file:        LICENSE
+author:              Ivan Lazar Miljenovic
+maintainer:          Ivan.Miljenovic@gmail.com
+-- copyright:
+category:            Data
+build-type:          Simple
+-- extra-source-files:
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     Data.Buildable
+  -- other-modules:
+  -- other-extensions:
+  build-depends:       base >=4.6 && <4.7
+                     , bytestring >= 0.10.0.0 && < 0.11
+                     , containers == 0.5.*
+                     , dlist >= 0.5 && < 0.8
+                     , text >= 0.11.3.0 && < 1.12
+  hs-source-dirs:      src
+  default-language:    Haskell2010
diff --git a/src/Data/Buildable.hs b/src/Data/Buildable.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Buildable.hs
@@ -0,0 +1,811 @@
+{-# LANGUAGE ConstraintKinds, FlexibleContexts, FlexibleInstances,
+             GeneralizedNewtypeDeriving, MultiParamTypeClasses,
+             OverlappingInstances, TypeFamilies, UndecidableInstances #-}
+
+{- |
+   Module      : Data.Buildable
+   Description : Builders for linear data structures
+   Copyright   : (c) Ivan Lazar Miljenovic
+   License     : 3-Clause BSD-style
+   Maintainer  : Ivan.Miljenovic@gmail.com
+
+Various linear data structures can be expensive to construct in a
+repetitive fashion.  For example, to append a single value to the end
+of a list is @O(n)@, and as such doing so repeatedly is recommended
+against.
+
+As such, to efficiently construct such structures we have the notion
+of a /builder/.  This can be used to more efficiently prepend and
+append values, and at the end we \"run\" the builder to construct the
+overall value.
+
+This module provides an abstraction over various builders for specific
+data structures.  It also aims to minimise the number of functions
+required to add various values to the builder by using a typeclass and
+newtype wrappers.
+
+To construct a value from it's builder:
+
+    1. Start with either @'mempty'@ for an empty 'Builder', or if you
+       have an initial value use @'fromValue'@.
+
+    2. Add initial values to the front or back using 'prepend' \/ '<|'
+       or 'append' \/ '|>' respectively.
+
+    3. Once you've finished constructing your builder, create your
+       final value with 'build'.
+
+/Note/: all instances are defined for both strict and lazy
+@ByteString@ and @Text@ values.
+
+ -}
+module Data.Buildable
+  ( -- * Typeclasses
+    Buildable (..)
+  , BuildFrom (..)
+  , CanBuildFrom
+  , singleton
+  , (<|)
+  , (|>)
+    -- * Chunked builder
+    -- $chunked
+  , Chunked (..)
+  , ChunkedBuilder (..)
+
+    -- * ByteString Builders
+    -- $bytestring
+
+    -- ** Numeric wrappers
+    -- $numeric
+  , BigEndian (..)
+  , LittleEndian (..)
+  , Dec (..)
+  , Hex (..)
+  , HexFixed (..)
+    -- ** Textual wrappers
+    -- $textual
+  , Char7 (..)
+  , Char8 (..)
+  , Utf8 (..)
+  , Utf16 (..)
+  , Utf32 (..)
+
+    -- * Text Builders
+    -- $text
+  ) where
+
+import Data.Monoid (Monoid (..), (<>))
+import Data.String (IsString (..))
+
+import qualified Data.DList as DL
+
+import qualified Data.ByteString                    as SB
+import qualified Data.ByteString.Lazy               as LB
+import qualified Data.ByteString.Lazy.Builder       as B
+import qualified Data.ByteString.Lazy.Builder.ASCII as B
+import           Data.Int
+import           Data.Word
+
+import qualified Data.Text               as ST
+import qualified Data.Text.Encoding      as ST
+import qualified Data.Text.Lazy          as LT
+import qualified Data.Text.Lazy.Builder  as T
+import qualified Data.Text.Lazy.Encoding as LT
+
+import qualified Data.Sequence as S
+
+-- -----------------------------------------------------------------------------
+
+-- | A linear data structure @a@ is buildable if we can prepend and
+--   append both values of the data structure in question and its
+--   constituent elements to the builder.
+class (BuildFrom (Builder a) a, BuildFrom (Builder a) (Unit a))
+      => Buildable a where
+
+  -- | The individual elements.
+  type Unit a
+
+  type Builder a
+
+  -- | Build the actual data structure.
+  build :: Builder a -> a
+
+-- | @CanBuildFrom b a@ states that we can build a value of type @b@
+--   with values of type @a@.
+type CanBuildFrom b a = (Buildable b, BuildFrom (Builder b) a)
+
+singleton :: (CanBuildFrom b a) => a -> b
+singleton = build . fromValue
+{-# INLINE [1] singleton #-}
+-- The [1] is to make sure the rule fires.
+
+{-# RULES
+
+"singleton/sametype" forall b. singleton b = b
+
+ #-}
+
+-- -----------------------------------------------------------------------------
+
+-- | Which values can be built from other values?
+--
+--   Minimal complete definition:
+--
+--     * @fromValue@
+class (Monoid b) => BuildFrom b a where
+
+  -- | Create a builder from an initial value.
+  fromValue :: a -> b
+
+  -- | Add a value to the front.
+  prepend :: a -> b -> b
+  prepend a b = fromValue a <> b
+
+  -- | Add a value to the end.
+  append :: b -> a -> b
+  append b a = b <> fromValue a
+
+-- | An alias for 'prepend'.
+--
+--   Mnemonic: the arrow points to the new value.
+(<|) :: (BuildFrom b a) => a -> b -> b
+(<|) = prepend
+
+infixr 4 <|
+
+-- | An alias for 'append'.
+--
+--   Mnemonic: the arrow points to the new value.
+(|>) :: (BuildFrom b a) => b -> a -> b
+(|>) = append
+
+infixl 5 |>
+-- Have this bind tighter than <| because if builders have a
+-- preference, it's that appends should be preferred (thus take care
+-- of any appends first before prepending as it might prove cheaper).
+
+-- -----------------------------------------------------------------------------
+-- Lists
+
+instance Buildable [a] where
+  type Unit [a] = a
+  type Builder [a] = DL.DList a
+
+  build = DL.toList
+
+instance BuildFrom [a] a where
+  fromValue = (: [])
+
+  prepend = (:)
+
+instance BuildFrom (DL.DList a) [a] where
+  fromValue = DL.fromList
+
+instance BuildFrom (DL.DList a) a where
+  fromValue = DL.singleton
+
+  prepend = DL.cons
+
+  append = DL.snoc
+
+instance BuildFrom (DL.DList [a]) a where
+  fromValue = DL.singleton . (: [])
+
+  prepend = DL.cons . (: [])
+
+  append b = DL.snoc b . (: [])
+
+-- -----------------------------------------------------------------------------
+-- Chunked builder
+
+{- $chunked
+
+For either testing purposes or some other reason, rather than actually
+creating an overall value you may actually want a list of a
+'Buildable' type.
+
+The 'Chunked' type allows you to efficiently create a list of such
+values by converting every provided value into the specified type.
+
+-}
+
+-- | An explicit chunkified representation of a Builder.  If we have a
+-- polymorphic expression @buildValue@ that can be used to build
+-- something of type @b@, then the following are equivalent:
+--
+--   > 'build' buildValue == mconcat . unChunk $ build buildValue
+newtype Chunked a = Chunks { unChunk :: [a]}
+  deriving (Eq, Ord, Show, Read, Monoid, Functor)
+
+-- | You probably won't actually need to use this type; it's defined
+--   solely to be the 'Builder' for 'Chunked'.
+newtype ChunkedBuilder a = CB { unCB :: DL.DList a }
+  deriving (Monoid, Functor)
+
+instance (Buildable b) => Buildable (Chunked b) where
+  type Unit (Chunked b) = b
+  type Builder (Chunked b) = ChunkedBuilder b
+
+  build = Chunks . DL.toList . unCB
+
+instance (Buildable b) => BuildFrom (ChunkedBuilder b) (Chunked b) where
+  fromValue = CB . DL.fromList . unChunk
+
+instance (CanBuildFrom b a) => BuildFrom (ChunkedBuilder b) a where
+  fromValue = CB . DL.singleton . singleton
+
+  prepend a (CB b) = CB (singleton a `DL.cons` b)
+
+  append (CB b) a = CB (b `DL.snoc` singleton a)
+
+-- -----------------------------------------------------------------------------
+-- ByteStrings
+
+{- $bytestring
+
+There are various ways that numeric and textual types can be built
+into part of a @ByteString@ (be it strict or lazy).  To be able to
+choose between these, various wrapper types have been defined.
+
+What you can add to the @ByteString@ Builder:
+
+    * Strict and lazy ByteStrings.
+
+    * Numeric types, though most require a wrapper to disambiguate
+      /how/ to add it (see below)/
+
+    * 'Char' and 'String' and both strict and lazy @Text@ values after
+      choosing an appropriate encoding (see below for wrapper types).
+
+-}
+
+-- | Strict ByteStrings.  This instance goes via lazy ByteStrings, and
+--   as such they should be preferred.
+instance Buildable SB.ByteString where
+  type Unit SB.ByteString = Word8
+  type Builder SB.ByteString = B.Builder
+
+  build = LB.toStrict . B.toLazyByteString
+
+{-# RULES "unbuild/SB.ByteString" forall b. LB.toStrict (B.toLazyByteString (B.byteString b)) = b #-}
+
+-- | Lazy ByteStrings.  This instance should be preferred over the one
+--   for strict ByteStrings.
+instance Buildable LB.ByteString where
+  type Unit LB.ByteString = Word8
+  type Builder LB.ByteString = B.Builder
+
+  build = B.toLazyByteString
+
+{-# RULES "unbuild/LB.ByteString" forall b. B.toLazyByteString (B.lazyByteString b) = b #-}
+
+{- $numeric
+
+Apart from 'Word8' and 'Int8', all numeric types need to be specified
+whether they should be encoded using 'BigEndian' or 'LittleEndian'
+format (with the exception of decimal representation using 'Dec').
+
+All wrappers derive the various numeric type classes so that you can
+still perform various calculations on them.
+
+-}
+
+-- | Explicitly state that a number should be encoded in big-endian
+--   format.
+newtype BigEndian a = BE { unBE :: a }
+  deriving ( Eq, Ord, Show, Read, Bounded, Enum
+           , Num, Integral, Real, RealFloat, RealFrac, Floating, Fractional)
+
+-- | Explicitly state that a number should be encoded in little-endian
+--   format.
+newtype LittleEndian a = LE { unLE :: a }
+  deriving ( Eq, Ord, Show, Read, Bounded, Enum
+           , Num, Integral, Real, RealFloat, RealFrac, Floating, Fractional)
+
+-- | Encode a number as its decimal representation with ASCII-encoded
+--   characters.
+newtype Dec a = Dec { unDec :: a }
+  deriving ( Eq, Ord, Show, Read, Bounded, Enum
+           , Num, Integral, Real, RealFloat, RealFrac, Floating, Fractional)
+
+-- | Encode a number as its hexadecimal representation with
+--   ASCII-encoded (lower-case) characters using the shortest possible
+--   representation.  For fixed-width encoding use 'HexFixed' instead.
+newtype Hex a = Hex { unHex :: a }
+  deriving ( Eq, Ord, Show, Read, Bounded, Enum
+           , Num, Integral, Real, RealFloat, RealFrac, Floating, Fractional)
+
+-- | Encode a number as its hexadecimal representation with
+--   ASCII-encoded (lower-case) characters using a fixed number of
+--   hexadecimal digits.  For shortest-width encoding use 'Hex'
+--   instead.
+newtype HexFixed a = HexFixed { unHexFixed :: a }
+  deriving ( Eq, Ord, Show, Read, Bounded, Enum
+           , Num, Integral, Real, RealFloat, RealFrac, Floating, Fractional)
+
+instance BuildFrom B.Builder SB.ByteString where
+  fromValue = B.byteString
+
+instance BuildFrom B.Builder (HexFixed SB.ByteString) where
+  fromValue = B.byteStringHexFixed . unHexFixed
+
+instance BuildFrom B.Builder LB.ByteString where
+  fromValue = B.lazyByteString
+
+instance BuildFrom B.Builder (HexFixed LB.ByteString) where
+  fromValue = B.lazyByteStringHexFixed . unHexFixed
+
+instance BuildFrom B.Builder Word8 where
+  fromValue = B.word8
+
+instance BuildFrom B.Builder (Dec Word8) where
+  fromValue = B.word8Dec . unDec
+
+instance BuildFrom B.Builder (Hex Word8) where
+  fromValue = B.word8Hex . unHex
+
+-- | Uses 2 nibbles/hexadecimal digits.
+instance BuildFrom B.Builder (HexFixed Word8) where
+  fromValue = B.word8HexFixed . unHexFixed
+
+instance BuildFrom B.Builder Int8 where
+  fromValue = B.int8
+
+instance BuildFrom B.Builder (Dec Int8) where
+  fromValue = B.int8Dec . unDec
+
+-- | Uses 2 nibbles/hexadecimal digits.
+instance BuildFrom B.Builder (HexFixed Int8) where
+  fromValue = B.int8HexFixed . unHexFixed
+
+instance BuildFrom B.Builder (BigEndian Double) where
+  fromValue = B.doubleBE . unBE
+
+instance BuildFrom B.Builder (LittleEndian Double) where
+  fromValue = B.doubleLE . unLE
+
+-- | Currently slow.
+instance BuildFrom B.Builder (Dec Double) where
+  fromValue = B.doubleDec . unDec
+
+-- | Uses 16 nibbles/hexadecimal digits.
+instance BuildFrom B.Builder (HexFixed Double) where
+  fromValue = B.doubleHexFixed . unHexFixed
+
+instance BuildFrom B.Builder (BigEndian Float) where
+  fromValue = B.floatBE . unBE
+
+instance BuildFrom B.Builder (LittleEndian Float) where
+  fromValue = B.floatLE . unLE
+
+-- | Currently slow.
+instance BuildFrom B.Builder (Dec Float) where
+  fromValue = B.floatDec . unDec
+
+-- | Uses 8 nibbles/hexadecimal digits.
+instance BuildFrom B.Builder (HexFixed Float) where
+  fromValue = B.floatHexFixed . unHexFixed
+
+instance BuildFrom B.Builder (BigEndian Int16) where
+  fromValue = B.int16BE . unBE
+
+instance BuildFrom B.Builder (LittleEndian Int16) where
+  fromValue = B.int16LE . unLE
+
+instance BuildFrom B.Builder (Dec Int16) where
+  fromValue = B.int16Dec . unDec
+
+-- | Uses 4 nibbles/hexadecimal digits.
+instance BuildFrom B.Builder (HexFixed Int16) where
+  fromValue = B.int16HexFixed . unHexFixed
+
+instance BuildFrom B.Builder (BigEndian Int32) where
+  fromValue = B.int32BE . unBE
+
+instance BuildFrom B.Builder (LittleEndian Int32) where
+  fromValue = B.int32LE . unLE
+
+instance BuildFrom B.Builder (Dec Int32) where
+  fromValue = B.int32Dec . unDec
+
+-- | Uses 8 nibbles/hexadecimal digits.
+instance BuildFrom B.Builder (HexFixed Int32) where
+  fromValue = B.int32HexFixed . unHexFixed
+
+instance BuildFrom B.Builder (BigEndian Int64) where
+  fromValue = B.int64BE . unBE
+
+instance BuildFrom B.Builder (LittleEndian Int64) where
+  fromValue = B.int64LE . unLE
+
+instance BuildFrom B.Builder (Dec Int64) where
+  fromValue = B.int64Dec . unDec
+
+-- | Uses 16 nibbles/hexadecimal digits.
+instance BuildFrom B.Builder (HexFixed Int64) where
+  fromValue = B.int64HexFixed . unHexFixed
+
+instance BuildFrom B.Builder (Dec Int) where
+  fromValue = B.intDec . unDec
+
+instance BuildFrom B.Builder (Dec Integer) where
+  fromValue = B.integerDec . unDec
+
+instance BuildFrom B.Builder (BigEndian Word16) where
+  fromValue = B.word16BE . unBE
+
+instance BuildFrom B.Builder (LittleEndian Word16) where
+  fromValue = B.word16LE . unLE
+
+instance BuildFrom B.Builder (Dec Word16) where
+  fromValue = B.word16Dec . unDec
+
+instance BuildFrom B.Builder (Hex Word16) where
+  fromValue = B.word16Hex . unHex
+
+-- | Uses 4 nibbles/hexadecimal digits.
+instance BuildFrom B.Builder (HexFixed Word16) where
+  fromValue = B.word16HexFixed . unHexFixed
+
+instance BuildFrom B.Builder (BigEndian Word32) where
+  fromValue = B.word32BE . unBE
+
+instance BuildFrom B.Builder (LittleEndian Word32) where
+  fromValue = B.word32LE . unLE
+
+instance BuildFrom B.Builder (Dec Word32) where
+  fromValue = B.word32Dec . unDec
+
+instance BuildFrom B.Builder (Hex Word32) where
+  fromValue = B.word32Hex . unHex
+
+-- | Uses 8 nibbles/hexadecimal digits.
+instance BuildFrom B.Builder (HexFixed Word32) where
+  fromValue = B.word32HexFixed . unHexFixed
+
+instance BuildFrom B.Builder (BigEndian Word64) where
+  fromValue = B.word64BE . unBE
+
+instance BuildFrom B.Builder (LittleEndian Word64) where
+  fromValue = B.word64LE . unLE
+
+instance BuildFrom B.Builder (Dec Word64) where
+  fromValue = B.word64Dec . unDec
+
+instance BuildFrom B.Builder (Hex Word64) where
+  fromValue = B.word64Hex . unHex
+
+-- | Uses 16 nibbles/hexadecimal digits.
+instance BuildFrom B.Builder (HexFixed Word64) where
+  fromValue = B.word64HexFixed . unHexFixed
+
+instance BuildFrom B.Builder (Dec Word) where
+  fromValue = B.wordDec . unDec
+
+instance BuildFrom B.Builder (Hex Word) where
+  fromValue = B.wordHex . unHex
+
+{- $textual
+
+There are various different encodings that can be used to encode
+textual data as a series of binary digits.  As such, it is necessary
+to specify which encoding you want to use.
+
+For 'Utf16' and 'Utf32' it is also necessary to specify whether you
+want to use a 'BigEndian' or 'LittleEndian' format; the order of
+newtype wrappers doesn't matter.
+
+These are also used to encode a @ByteString@ into the 'Builder' for
+@Text@ values (both strict and lazy).
+
+-}
+
+-- | Unicode codepoints are truncated to 7 bits and prefixed with a
+--   leading 0.  For the codepoints 0-127 this corresponds to the
+--   ASCII encoding.
+newtype Char7 a = Char7 { unChar7 :: a }
+  deriving (Eq, Ord, Show, Read, Bounded, Enum)
+
+instance (IsString a) => IsString (Char7 a) where
+  fromString = Char7 . fromString
+
+-- | Unicode codepoints are truncated to 8 bits.  For the codepoints
+--   0-255 this corresponds to the ISO/IEC 8859-1 (aka Latin-1)
+--   encoding.
+newtype Char8 a = Char8 { unChar8 :: a }
+  deriving (Eq, Ord, Show, Read, Bounded, Enum)
+
+instance (IsString a) => IsString (Char8 a) where
+  fromString = Char8 . fromString
+
+-- | Encode a textual value using UTF-8.
+newtype Utf8 a = Utf8 { unUtf8 :: a }
+  deriving (Eq, Ord, Show, Read, Bounded, Enum)
+
+instance (IsString a) => IsString (Utf8 a) where
+  fromString = Utf8 . fromString
+
+-- | Encode a textual value using UTF-16.
+--
+--   Needs to be used with either 'BigEndian' or 'LittleEndian'.
+newtype Utf16 a = Utf16 { unUtf16 :: a }
+  deriving (Eq, Ord, Show, Read, Bounded, Enum)
+
+instance (IsString a) => IsString (Utf16 a) where
+  fromString = Utf16 . fromString
+
+-- | Encode a textual value using UTF-32.
+--
+--   Needs to be used with either 'BigEndian' or 'LittleEndian'.
+newtype Utf32 a = Utf32 { unUtf32 :: a }
+  deriving (Eq, Ord, Show, Read, Bounded, Enum)
+
+instance (IsString a) => IsString (Utf32 a) where
+  fromString = Utf32 . fromString
+
+instance BuildFrom B.Builder (Char7 Char) where
+  fromValue = B.char7 . unChar7
+
+instance BuildFrom B.Builder (Char8 Char) where
+  fromValue = B.char8 . unChar8
+
+instance BuildFrom B.Builder (Utf8 Char) where
+  fromValue = B.charUtf8 . unUtf8
+
+instance BuildFrom B.Builder (Char7 String) where
+  fromValue = B.string7 . unChar7
+
+instance BuildFrom B.Builder (Char8 String) where
+  fromValue = B.string8 . unChar8
+
+instance BuildFrom B.Builder (Utf8 String) where
+  fromValue = B.stringUtf8 . unUtf8
+
+-- | For strict Text values; goes via a strict ByteString.
+instance BuildFrom B.Builder (Utf8 ST.Text) where
+  fromValue = B.byteString . ST.encodeUtf8 . unUtf8
+
+-- | For strict Text values; goes via a strict ByteString.  Equivalent
+--   to the @Utf16 (BigEndian Text)@ instance.
+instance BuildFrom B.Builder (BigEndian (Utf16 ST.Text)) where
+  fromValue = B.byteString . ST.encodeUtf16BE . unUtf16 . unBE
+
+-- | For strict Text values; goes via a strict ByteString.  Equivalent
+--   to the @BigEndian (Utf16 Text)@ instance.
+instance BuildFrom B.Builder (Utf16 (BigEndian ST.Text)) where
+  fromValue = B.byteString . ST.encodeUtf16BE . unBE . unUtf16
+
+-- | For strict Text values; goes via a strict ByteString.  Equivalent
+--   to the @Utf16 (LittleEndian Text)@ instance.
+instance BuildFrom B.Builder (LittleEndian (Utf16 ST.Text)) where
+  fromValue = B.byteString . ST.encodeUtf16LE . unUtf16 . unLE
+
+-- | For strict Text values; goes via a strict ByteString.  Equivalent
+--   to the @LittleEndian (Utf16 Text)@ instance.
+instance BuildFrom B.Builder (Utf16 (LittleEndian ST.Text)) where
+  fromValue = B.byteString . ST.encodeUtf16LE . unLE . unUtf16
+
+-- | For strict Text values; goes via a strict ByteString.  Equivalent
+--   to the @Utf32 (BigEndian Text)@ instance.
+instance BuildFrom B.Builder (BigEndian (Utf32 ST.Text)) where
+  fromValue = B.byteString . ST.encodeUtf32BE . unUtf32 . unBE
+
+-- | For strict Text values; goes via a strict ByteString.  Equivalent
+--   to the @BigEndian (Utf32 Text)@ instance.
+instance BuildFrom B.Builder (Utf32 (BigEndian ST.Text)) where
+  fromValue = B.byteString . ST.encodeUtf32BE . unBE . unUtf32
+
+-- | For strict Text values; goes via a strict ByteString.  Equivalent
+--   to the @Utf32 (LittleEndian Text)@ instance.
+instance BuildFrom B.Builder (LittleEndian (Utf32 ST.Text)) where
+  fromValue = B.byteString . ST.encodeUtf32LE . unUtf32 . unLE
+
+-- | For strict Text values; goes via a strict ByteString.  Equivalent
+--   to the @LittleEndian (Utf32 Text)@ instance.
+instance BuildFrom B.Builder (Utf32 (LittleEndian ST.Text)) where
+  fromValue = B.byteString . ST.encodeUtf32LE . unLE . unUtf32
+
+-- | For lazy Text values; goes via a lazy ByteString.
+instance BuildFrom B.Builder (Utf8 LT.Text) where
+  fromValue = B.lazyByteString . LT.encodeUtf8 . unUtf8
+
+-- | For lazy Text values; goes via a lazy ByteString.  Equivalent
+--   to the @Utf16 (BigEndian Text)@ instance.
+instance BuildFrom B.Builder (BigEndian (Utf16 LT.Text)) where
+  fromValue = B.lazyByteString . LT.encodeUtf16BE . unUtf16 . unBE
+
+-- | For lazy Text values; goes via a lazy ByteString.  Equivalent
+--   to the @BigEndian (Utf16 Text)@ instance.
+instance BuildFrom B.Builder (Utf16 (BigEndian LT.Text)) where
+  fromValue = B.lazyByteString . LT.encodeUtf16BE . unBE . unUtf16
+
+-- | For lazy Text values; goes via a lazy ByteString.  Equivalent
+--   to the @Utf16 (LittleEndian Text)@ instance.
+instance BuildFrom B.Builder (LittleEndian (Utf16 LT.Text)) where
+  fromValue = B.lazyByteString . LT.encodeUtf16LE . unUtf16 . unLE
+
+-- | For lazy Text values; goes via a lazy ByteString.  Equivalent
+--   to the @LittleEndian (Utf16 Text)@ instance.
+instance BuildFrom B.Builder (Utf16 (LittleEndian LT.Text)) where
+  fromValue = B.lazyByteString . LT.encodeUtf16LE . unLE . unUtf16
+
+-- | For lazy Text values; goes via a lazy ByteString.  Equivalent
+--   to the @Utf32 (BigEndian Text)@ instance.
+instance BuildFrom B.Builder (BigEndian (Utf32 LT.Text)) where
+  fromValue = B.lazyByteString . LT.encodeUtf32BE . unUtf32 . unBE
+
+-- | For lazy Text values; goes via a lazy ByteString.  Equivalent
+--   to the @BigEndian (Utf32 Text)@ instance.
+instance BuildFrom B.Builder (Utf32 (BigEndian LT.Text)) where
+  fromValue = B.lazyByteString . LT.encodeUtf32BE . unBE . unUtf32
+
+-- | For lazy Text values; goes via a lazy ByteString.  Equivalent
+--   to the @Utf32 (LittleEndian Text)@ instance.
+instance BuildFrom B.Builder (LittleEndian (Utf32 LT.Text)) where
+  fromValue = B.lazyByteString . LT.encodeUtf32LE . unUtf32 . unLE
+
+-- | For lazy Text values; goes via a lazy ByteString.  Equivalent
+--   to the @LittleEndian (Utf32 Text)@ instance.
+instance BuildFrom B.Builder (Utf32 (LittleEndian LT.Text)) where
+  fromValue = B.lazyByteString . LT.encodeUtf32LE . unLE . unUtf32
+
+-- -----------------------------------------------------------------------------
+-- Text
+
+{- $text
+
+Both strict and lazy @Text@ values can be constructed via the text
+Builder, though the latter is preferred.
+
+Values that they can be built from:
+
+    * Strict and lazy @Text@ values.
+
+    * 'Char' and 'String' values directly.
+
+    * Strict and lazy 'ByteStrings' after choosing an appropriate
+      encoding.
+
+-}
+
+instance Buildable ST.Text where
+  type Unit ST.Text = Char
+  type Builder ST.Text = T.Builder
+
+  build = LT.toStrict . T.toLazyText
+
+instance Buildable LT.Text where
+  type Unit LT.Text = Char
+  type Builder LT.Text = T.Builder
+
+  build = T.toLazyText
+
+instance BuildFrom T.Builder ST.Text where
+  fromValue = T.fromText
+
+instance BuildFrom T.Builder LT.Text where
+  fromValue = T.fromLazyText
+
+instance BuildFrom T.Builder Char where
+  fromValue = T.singleton
+
+instance BuildFrom T.Builder String where
+  fromValue = T.fromString
+
+-- | For strict ByteStrings; goes via a strict Text.
+instance BuildFrom T.Builder (Char8 SB.ByteString) where
+  fromValue = T.fromText . ST.decodeLatin1 . unChar8
+
+-- | For strict ByteStrings; goes via a strict Text.
+instance BuildFrom T.Builder (Utf8 SB.ByteString) where
+  fromValue = T.fromText . ST.decodeUtf8 . unUtf8
+
+-- | For strict ByteStrings; goes via a strict Text.  Equivalent to
+--   the @Utf16 (BigEndian ByteString)@ instance.
+instance BuildFrom T.Builder (BigEndian (Utf16 SB.ByteString)) where
+  fromValue = T.fromText . ST.decodeUtf16BE . unUtf16 . unBE
+
+-- | For strict ByteStrings; goes via a strict Text.  Equivalent to
+--   the @BigEndian (Utf16 ByteString)@ instance.
+instance BuildFrom T.Builder (Utf16 (BigEndian SB.ByteString)) where
+  fromValue = T.fromText . ST.decodeUtf16BE . unBE . unUtf16
+
+-- | For strict ByteStrings; goes via a strict Text.  Equivalent to
+--   the @Utf16 (LittleEndian ByteString)@ instance.
+instance BuildFrom T.Builder (LittleEndian (Utf16 SB.ByteString)) where
+  fromValue = T.fromText . ST.decodeUtf16LE . unUtf16 . unLE
+
+-- | For strict ByteStrings; goes via a strict Text.  Equivalent to
+--   the @LittleEndian (Utf16 ByteString)@ instance.
+instance BuildFrom T.Builder (Utf16 (LittleEndian SB.ByteString)) where
+  fromValue = T.fromText . ST.decodeUtf16LE . unLE . unUtf16
+
+-- | For strict ByteStrings; goes via a strict Text.  Equivalent to
+--   the @Utf32 (BigEndian ByteString)@ instance.
+instance BuildFrom T.Builder (BigEndian (Utf32 SB.ByteString)) where
+  fromValue = T.fromText . ST.decodeUtf32BE . unUtf32 . unBE
+
+-- | For strict ByteStrings; goes via a strict Text.  Equivalent to
+--   the @BigEndian (Utf32 ByteString)@ instance.
+instance BuildFrom T.Builder (Utf32 (BigEndian SB.ByteString)) where
+  fromValue = T.fromText . ST.decodeUtf32BE . unBE . unUtf32
+
+-- | For strict ByteStrings; goes via a strict Text.  Equivalent to
+--   the @Utf32 (LittleEndian ByteString)@ instance.
+instance BuildFrom T.Builder (LittleEndian (Utf32 SB.ByteString)) where
+  fromValue = T.fromText . ST.decodeUtf32LE . unUtf32 . unLE
+
+-- | For strict ByteStrings; goes via a strict Text.  Equivalent to
+--   the @LittleEndian (Utf32 ByteString)@ instance.
+instance BuildFrom T.Builder (Utf32 (LittleEndian SB.ByteString)) where
+  fromValue = T.fromText . ST.decodeUtf32LE . unLE . unUtf32
+
+-- | For lazy ByteStrings; goes via a lazy Text.
+instance BuildFrom T.Builder (Char8 LB.ByteString) where
+  fromValue = T.fromLazyText . LT.decodeLatin1 . unChar8
+
+-- | For lazy ByteStrings; goes via a lazy Text.
+instance BuildFrom T.Builder (Utf8 LB.ByteString) where
+  fromValue = T.fromLazyText . LT.decodeUtf8 . unUtf8
+
+-- | For lazy ByteStrings; goes via a lazy Text.  Equivalent to
+--   the @Utf16 (BigEndian ByteString)@ instance.
+instance BuildFrom T.Builder (BigEndian (Utf16 LB.ByteString)) where
+  fromValue = T.fromLazyText . LT.decodeUtf16BE . unUtf16 . unBE
+
+-- | For lazy ByteStrings; goes via a lazy Text.  Equivalent to
+--   the @BigEndian (Utf16 ByteString)@ instance.
+instance BuildFrom T.Builder (Utf16 (BigEndian LB.ByteString)) where
+  fromValue = T.fromLazyText . LT.decodeUtf16BE . unBE . unUtf16
+
+-- | For lazy ByteStrings; goes via a lazy Text.  Equivalent to
+--   the @Utf16 (LittleEndian ByteString)@ instance.
+instance BuildFrom T.Builder (LittleEndian (Utf16 LB.ByteString)) where
+  fromValue = T.fromLazyText . LT.decodeUtf16LE . unUtf16 . unLE
+
+-- | For lazy ByteStrings; goes via a lazy Text.  Equivalent to
+--   the @LittleEndian (Utf16 ByteString)@ instance.
+instance BuildFrom T.Builder (Utf16 (LittleEndian LB.ByteString)) where
+  fromValue = T.fromLazyText . LT.decodeUtf16LE . unLE . unUtf16
+
+-- | For lazy ByteStrings; goes via a lazy Text.  Equivalent to
+--   the @Utf32 (BigEndian ByteString)@ instance.
+instance BuildFrom T.Builder (BigEndian (Utf32 LB.ByteString)) where
+  fromValue = T.fromLazyText . LT.decodeUtf32BE . unUtf32 . unBE
+
+-- | For lazy ByteStrings; goes via a lazy Text.  Equivalent to
+--   the @BigEndian (Utf32 ByteString)@ instance.
+instance BuildFrom T.Builder (Utf32 (BigEndian LB.ByteString)) where
+  fromValue = T.fromLazyText . LT.decodeUtf32BE . unBE . unUtf32
+
+-- | For lazy ByteStrings; goes via a lazy Text.  Equivalent to
+--   the @Utf32 (LittleEndian ByteString)@ instance.
+instance BuildFrom T.Builder (LittleEndian (Utf32 LB.ByteString)) where
+  fromValue = T.fromLazyText . LT.decodeUtf32LE . unUtf32 . unLE
+
+-- | For lazy ByteStrings; goes via a lazy Text.  Equivalent to
+--   the @LittleEndian (Utf32 ByteString)@ instance.
+instance BuildFrom T.Builder (Utf32 (LittleEndian LB.ByteString)) where
+  fromValue = T.fromLazyText . LT.decodeUtf32LE . unLE . unUtf32
+
+-- -----------------------------------------------------------------------------
+-- Sequences
+
+instance Buildable (S.Seq a) where
+  type Unit (S.Seq a) = a
+  type Builder (S.Seq a) = S.Seq a
+
+  build = id
+
+instance BuildFrom (S.Seq a) (S.Seq a) where
+  fromValue = id
+
+instance BuildFrom (S.Seq a) a where
+  fromValue = S.singleton
+
+  prepend = (S.<|)
+
+  append = (S.|>)
+
+instance BuildFrom (S.Seq a) [a] where
+  fromValue = S.fromList
