    {-# LANGUAGE CPP
                ,MultiParamTypeClasses
                ,TypeFamilies
                ,FlexibleInstances #-}
    {-# OPTIONS -Wno-orphans #-}

    module Data.ListLike.Text.Builder

    where

    import           Control.DeepSeq (NFData(rnf))
    import qualified Data.Text.Lazy.Builder as Builder
    import           Data.ListLike.Base as LL
    import           Data.ListLike.FoldableLL as LL
    import           Data.ListLike.IO
    import           Data.ListLike.String as LL
    import           Data.ListLike.Text.TextLazy ()
    --import           Data.String (IsString(fromString))
    import           GHC.Exts (IsList(..))

    instance FoldableLL Builder.Builder Char where
        foldl :: forall a. (a -> Char -> a) -> a -> Builder -> a
    foldl a -> Char -> a
    f a
    r0 = (a -> Char -> a) -> a -> Text -> a
    forall a. (a -> Char -> a) -> a -> Text -> a
    forall full item a.
    FoldableLL full item =>
    (a -> item -> a) -> a -> full -> a
    LL.foldl a -> Char -> a
    f a
    r0 (Text -> a) -> (Builder -> Text) -> Builder -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> Text
    Builder.toLazyText
        foldr :: forall b. (Char -> b -> b) -> b -> Builder -> b
    foldr Char -> b -> b
    f b
    r0 = (Char -> b -> b) -> b -> Text -> b
    forall b. (Char -> b -> b) -> b -> Text -> b
    forall full item b.
    FoldableLL full item =>
    (item -> b -> b) -> b -> full -> b
    LL.foldr Char -> b -> b
    f b
    r0 (Text -> b) -> (Builder -> Text) -> Builder -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> Text
    Builder.toLazyText

    instance IsList Builder.Builder where
        type Item Builder.Builder = Char
        -- Can we do better?
        toList :: Builder -> [Item Builder]
    toList = Builder -> [Char]
    Builder -> [Item Builder]
    forall full item. ListLike full item => full -> [item]
    LL.toList'
        fromList :: [Item Builder] -> Builder
    fromList = [Char] -> Builder
    [Item Builder] -> Builder
    forall full item. ListLike full item => [item] -> full
    LL.fromList'

    instance ListLike Builder.Builder Char where
        singleton :: Char -> Builder
    singleton = Char -> Builder
    Builder.singleton
        uncons :: Builder -> Maybe (Char, Builder)
    uncons Builder
    b = case Text -> Maybe (Char, Text)
    forall full item. ListLike full item => full -> Maybe (item, full)
    LL.uncons (Builder -> Text
    Builder.toLazyText Builder
    b) of
                     Maybe (Char, Text)
    Nothing -> Maybe (Char, Builder)
    forall a. Maybe a
    Nothing
                     Just (Char
    c, Text
    s) -> (Char, Builder) -> Maybe (Char, Builder)
    forall a. a -> Maybe a
    Just (Char
    c, Text -> Builder
    Builder.fromLazyText Text
    s)
        null :: Builder -> Bool
    null = Text -> Bool
    forall full item. ListLike full item => full -> Bool
    LL.null (Text -> Bool) -> (Builder -> Text) -> Builder -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> Text
    Builder.toLazyText

    instance ListLikeIO Builder.Builder Char where
        hGetLine :: Handle -> IO Builder
    hGetLine Handle
    h = Text -> Builder
    Builder.fromLazyText (Text -> Builder) -> IO Text -> IO Builder
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Handle -> IO Text
    forall full item. ListLikeIO full item => Handle -> IO full
    hGetLine Handle
    h
        hGetContents :: Handle -> IO Builder
    hGetContents Handle
    h = Text -> Builder
    Builder.fromLazyText (Text -> Builder) -> IO Text -> IO Builder
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Handle -> IO Text
    forall full item. ListLikeIO full item => Handle -> IO full
    hGetContents Handle
    h
        hGet :: Handle -> Int -> IO Builder
    hGet Handle
    h Int
    n = Text -> Builder
    Builder.fromLazyText (Text -> Builder) -> IO Text -> IO Builder
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Handle -> Int -> IO Text
    forall full item. ListLikeIO full item => Handle -> Int -> IO full
    hGet Handle
    h Int
    n
        hGetNonBlocking :: Handle -> Int -> IO Builder
    hGetNonBlocking Handle
    h Int
    n = Text -> Builder
    Builder.fromLazyText (Text -> Builder) -> IO Text -> IO Builder
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Handle -> Int -> IO Text
    forall full item. ListLikeIO full item => Handle -> Int -> IO full
    hGetNonBlocking Handle
    h Int
    n
        hPutStr :: Handle -> Builder -> IO ()
    hPutStr Handle
    h = Handle -> Text -> IO ()
    forall full item. ListLikeIO full item => Handle -> full -> IO ()
    hPutStr Handle
    h (Text -> IO ()) -> (Builder -> Text) -> Builder -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> Text
    Builder.toLazyText

    instance StringLike Builder.Builder where
        toString :: Builder -> [Char]
    toString = Text -> [Char]
    forall s. StringLike s => s -> [Char]
    toString (Text -> [Char]) -> (Builder -> Text) -> Builder -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> Text
    Builder.toLazyText
        fromText :: StringLike Text => Text -> Builder
    fromText = Text -> Builder
    Builder.fromText
        fromLazyText :: StringLike Text => Text -> Builder
    fromLazyText = Text -> Builder
    Builder.fromLazyText

    instance NFData Builder.Builder where
        rnf :: Builder -> ()
    rnf = Text -> ()
    forall a. NFData a => a -> ()
    rnf (Text -> ()) -> (Builder -> Text) -> Builder -> ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> Text
    Builder.toLazyText