    {-# LANGUAGE CPP, DeriveFunctor, TypeSynonymInstances, FlexibleInstances, TypeFamilies #-}
    -- |
    -- The `build` function can be used to construct multi-line string literals in
    -- a monadic way:
    --
    -- > {-# LANGUAGE OverloadedStrings #-}
    -- >
    -- > import Data.String.Builder
    -- >
    -- > mystring :: String
    -- > mystring = build $ do
    -- >   "foo"
    -- >   "bar"
    -- >   "baz"
    module Data.String.Builder (
    -- * Functions
      build
    , literal
    -- * Types
    , Builder
    , BuilderM
    ) where

    import           Control.Applicative
    import           Control.Monad
    import           Data.Monoid
    import           Data.String

    -- | A writer monad for string literals.
    data BuilderM a = BuilderM a ShowS
      deriving (forall a b. (a -> b) -> BuilderM a -> BuilderM b)
    -> (forall a b. a -> BuilderM b -> BuilderM a) -> Functor BuilderM
    forall a b. a -> BuilderM b -> BuilderM a
    forall a b. (a -> b) -> BuilderM a -> BuilderM b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall a b. (a -> b) -> BuilderM a -> BuilderM b
    fmap :: forall a b. (a -> b) -> BuilderM a -> BuilderM b
    $c<$ :: forall a b. a -> BuilderM b -> BuilderM a
    <$ :: forall a b. a -> BuilderM b -> BuilderM a
    Functor

    instance Applicative BuilderM where
      pure :: forall a. a -> BuilderM a
    pure = a -> BuilderM a
    forall a. a -> BuilderM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return
      <*> :: forall a b. BuilderM (a -> b) -> BuilderM a -> BuilderM b
    (<*>) = BuilderM (a -> b) -> BuilderM a -> BuilderM b
    forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
    ap

    instance Monad BuilderM where
      return :: forall a. a -> BuilderM a
    return a
    a            = a -> ShowS -> BuilderM a
    forall a. a -> ShowS -> BuilderM a
    BuilderM a
    a ShowS
    forall a. a -> a
    id
      BuilderM a
    a ShowS
    xs >>= :: forall a b. BuilderM a -> (a -> BuilderM b) -> BuilderM b
    >>= a -> BuilderM b
    f = case a -> BuilderM b
    f a
    a of
        BuilderM b
    b ShowS
    ys -> b -> ShowS -> BuilderM b
    forall a. a -> ShowS -> BuilderM a
    BuilderM b
    b (ShowS
    xs ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ShowS
    ys)

    type Builder = BuilderM ()

    instance Monoid Builder where
      mempty :: Builder
    mempty = () -> Builder
    forall a. a -> BuilderM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
    #if !MIN_VERSION_base(4,11,0)
      mappend = (>>)
    #else
    instance Semigroup Builder where
      <> :: Builder -> Builder -> Builder
    (<>) = Builder -> Builder -> Builder
    forall a b. BuilderM a -> BuilderM b -> BuilderM b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    (>>)
    #endif

    -- | Add a literal string.
    literal :: String -> Builder
    literal :: String -> Builder
    literal = () -> ShowS -> Builder
    forall a. a -> ShowS -> BuilderM a
    BuilderM () (ShowS -> Builder) -> (String -> ShowS) -> String -> Builder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> ShowS
    showString

    instance (a ~ ()) => IsString (BuilderM a) where
      fromString :: String -> BuilderM a
    fromString String
    s = String -> Builder
    literal String
    s Builder -> BuilderM a -> BuilderM a
    forall a b. BuilderM a -> BuilderM b -> BuilderM b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> String -> Builder
    literal String
    "\n"

    -- | Run a builder.
    build :: Builder -> String
    build :: Builder -> String
    build (BuilderM () ShowS
    s) = ShowS
    s String
    ""