    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE FunctionalDependencies #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE FlexibleContexts #-}
    -- | Abstraction for different kinds of builders.
    --
    -- Note that whenever a character encoding is used, it will be UTF8. For
    -- different behavior, please use the underlying library.
    module Data.Builder
        ( TextBuilder
        , BlazeBuilder
        , ByteStringBuilder
        , Builder (..)
        , ToBuilder (..)
        , textToBuilder
        ) where

    import Data.Monoid (Monoid)

    import qualified Data.Text as T
    import qualified Data.Text.Lazy as TL
    import qualified Data.Text.Lazy.Builder as TB

    import qualified Data.ByteString as S
    import qualified Data.ByteString.Lazy as L
    import qualified Data.ByteString.Builder as BB
    import qualified Data.ByteString.Builder.Extra as BB (flush)

    import qualified Data.Text.Encoding as TE
    import qualified Data.Text.Lazy.Encoding as TLE

    -- | Since 0.1.0.0
    type TextBuilder = TB.Builder

    -- | Since 0.1.0.0
    type BlazeBuilder = BB.Builder

    -- | Since 0.3.0.0
    type ByteStringBuilder = BB.Builder

    -- | Since 0.1.0.0
    class Monoid builder => Builder builder lazy | builder -> lazy, lazy -> builder where
        -- | Since 0.1.0.0
        builderToLazy :: builder -> lazy

        -- | Since 0.1.0.0
        flushBuilder :: builder

    instance Builder TB.Builder TL.Text where
        builderToLazy :: Builder -> Text
    builderToLazy = Builder -> Text
    TB.toLazyText
        flushBuilder :: Builder
    flushBuilder = Builder
    TB.flush

    instance Builder BB.Builder L.ByteString where
        builderToLazy :: Builder -> ByteString
    builderToLazy = Builder -> ByteString
    BB.toLazyByteString
        flushBuilder :: Builder
    flushBuilder = Builder
    BB.flush

    -- | Since 0.1.0.0
    class ToBuilder value builder where
        -- | Since 0.1.0.0
        toBuilder :: value -> builder

    -- Text
    instance ToBuilder TB.Builder TB.Builder where
        toBuilder :: Builder -> Builder
    toBuilder = Builder -> Builder
    forall a. a -> a
    id
    instance ToBuilder T.Text TB.Builder where
        toBuilder :: Text -> Builder
    toBuilder = Text -> Builder
    TB.fromText
    instance ToBuilder TL.Text TB.Builder where
        toBuilder :: Text -> Builder
    toBuilder = Text -> Builder
    TB.fromLazyText
    instance ToBuilder Char TB.Builder where
        toBuilder :: Char -> Builder
    toBuilder = Char -> Builder
    TB.singleton
    instance (a ~ Char) => ToBuilder [a] TB.Builder where
        toBuilder :: [a] -> Builder
    toBuilder = [a] -> Builder
    String -> Builder
    TB.fromString

    -- Blaze
    instance ToBuilder BB.Builder BB.Builder where
        toBuilder :: Builder -> Builder
    toBuilder = Builder -> Builder
    forall a. a -> a
    id
    instance ToBuilder T.Text BB.Builder where
        toBuilder :: Text -> Builder
    toBuilder = Text -> Builder
    TE.encodeUtf8Builder
    instance ToBuilder TL.Text BB.Builder where
        toBuilder :: Text -> Builder
    toBuilder = Text -> Builder
    TLE.encodeUtf8Builder
    instance ToBuilder Char BB.Builder where
        toBuilder :: Char -> Builder
    toBuilder = Text -> Builder
    forall value builder. ToBuilder value builder => value -> builder
    toBuilder (Text -> Builder) -> (Char -> Text) -> Char -> Builder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> Text
    T.singleton
    instance (a ~ Char) => ToBuilder [a] BB.Builder where
        toBuilder :: [a] -> Builder
    toBuilder = Text -> Builder
    forall value builder. ToBuilder value builder => value -> builder
    toBuilder (Text -> Builder) -> ([a] -> Text) -> [a] -> Builder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Text
    String -> Text
    TL.pack

    instance ToBuilder S.ByteString BB.Builder where
        toBuilder :: ByteString -> Builder
    toBuilder = ByteString -> Builder
    BB.byteString
    instance ToBuilder L.ByteString BB.Builder where
        toBuilder :: ByteString -> Builder
    toBuilder = ByteString -> Builder
    BB.lazyByteString

    -- | Provided for type disambiguation in the presence of OverloadedStrings.
    --
    -- Since 0.1.0.0
    textToBuilder :: ToBuilder T.Text builder => T.Text -> builder
    textToBuilder :: forall builder. ToBuilder Text builder => Text -> builder
    textToBuilder = Text -> builder
    forall value builder. ToBuilder value builder => value -> builder
    toBuilder