    module TextBuilder.Domains.Combinators where

    import TextBuilder.Prelude hiding (intercalate)
    import TextBuilderCore

    -- |
    -- Run the builder and pack the produced text into a new builder.
    --
    -- Useful to have around builders that you reuse,
    -- because a forced builder is much faster,
    -- since it's virtually a single call to @memcopy@.
    {-# INLINE force #-}
    force :: TextBuilder -> TextBuilder
    force :: TextBuilder -> TextBuilder
    force = Text -> TextBuilder
    text (Text -> TextBuilder)
    -> (TextBuilder -> Text) -> TextBuilder -> TextBuilder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . TextBuilder -> Text
    toText

    -- | Intercalate builders.
    --
    -- >>> intercalate ", " ["a", "b", "c"]
    -- "a, b, c"
    --
    -- >>> intercalate ", " ["a"]
    -- "a"
    --
    -- >>> intercalate ", " []
    -- ""
    {-# INLINE intercalate #-}
    intercalate :: (Foldable f) => TextBuilder -> f TextBuilder -> TextBuilder
    intercalate :: forall (f :: * -> *).
    Foldable f =>
    TextBuilder -> f TextBuilder -> TextBuilder
    intercalate TextBuilder
    separator f TextBuilder
    elements =
      (TextBuilder
     -> (TextBuilder -> TextBuilder) -> TextBuilder -> TextBuilder)
    -> (TextBuilder -> TextBuilder)
    -> f TextBuilder
    -> TextBuilder
    -> TextBuilder
    forall a b. (a -> b -> b) -> b -> f a -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr
        (\TextBuilder
    element TextBuilder -> TextBuilder
    next TextBuilder
    prefix -> TextBuilder
    prefix TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder
    element TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder -> TextBuilder
    next TextBuilder
    separator)
        (TextBuilder -> TextBuilder -> TextBuilder
    forall a b. a -> b -> a
    const TextBuilder
    forall a. Monoid a => a
    mempty)
        f TextBuilder
    elements
        TextBuilder
    forall a. Monoid a => a
    mempty

    -- | Intercalate projecting values to builder.
    {-# INLINE intercalateMap #-}
    intercalateMap :: (Foldable f) => TextBuilder -> (a -> TextBuilder) -> f a -> TextBuilder
    intercalateMap :: forall (f :: * -> *) a.
    Foldable f =>
    TextBuilder -> (a -> TextBuilder) -> f a -> TextBuilder
    intercalateMap TextBuilder
    separator a -> TextBuilder
    mapper = Maybe TextBuilder -> TextBuilder
    forall {a}. Monoid a => Maybe a -> a
    extract (Maybe TextBuilder -> TextBuilder)
    -> (f a -> Maybe TextBuilder) -> f a -> TextBuilder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (Maybe TextBuilder -> a -> Maybe TextBuilder)
    -> Maybe TextBuilder -> f a -> Maybe TextBuilder
    forall b a. (b -> a -> b) -> b -> f a -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' Maybe TextBuilder -> a -> Maybe TextBuilder
    step Maybe TextBuilder
    forall {a}. Maybe a
    init
      where
        init :: Maybe a
    init = Maybe a
    forall {a}. Maybe a
    Nothing
        step :: Maybe TextBuilder -> a -> Maybe TextBuilder
    step Maybe TextBuilder
    acc a
    element =
          TextBuilder -> Maybe TextBuilder
    forall a. a -> Maybe a
    Just (TextBuilder -> Maybe TextBuilder)
    -> TextBuilder -> Maybe TextBuilder
    forall a b. (a -> b) -> a -> b
    $ case Maybe TextBuilder
    acc of
            Maybe TextBuilder
    Nothing -> a -> TextBuilder
    mapper a
    element
            Just TextBuilder
    acc -> TextBuilder
    acc TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder
    separator TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> a -> TextBuilder
    mapper a
    element
        extract :: Maybe a -> a
    extract = a -> Maybe a -> a
    forall a. a -> Maybe a -> a
    fromMaybe a
    forall a. Monoid a => a
    mempty