    {-# language MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances, CPP #-}

    -- | A type class for converting strings.
    -- Supported types are:
    --
    --     * 'String'
    --
    --     * strict 'Data.ByteString.ByteString'
    --
    --     * lazy 'Data.ByteString.Lazy.ByteString'
    --
    --     * strict 'Data.Text.Text'
    --
    --     * lazy 'Data.Text.Lazy.Text'
    --
    -- Assumes UTF-8 encoding for both types of ByteStrings.

    module Data.String.Conversions (
        -- * class and conversions
        ConvertibleStrings(..),
        cs,

        -- * type synonyms
        StrictByteString,
        SBS,
        LazyByteString,
        LBS,
        StrictText,
        ST,
        LazyText,
        LT,

        -- | Generic string concatenation (with ghc >= 7.4 this is a re-export from Data.Monoid
        -- to avoid clashes.)
        (<>),
      ) where

    import Data.Monoid

    #if !MIN_VERSION_base(4,8,0)
    import Control.Applicative
    #endif

    -- string imports

    import qualified Data.ByteString
    import qualified Data.ByteString.UTF8

    import qualified Data.ByteString.Lazy
    import qualified Data.ByteString.Lazy.UTF8

    import qualified Data.Text
    import qualified Data.Text.Encoding hiding (decodeUtf8)
    import qualified Data.Text.Encoding.Error

    import qualified Data.Text.Lazy
    import qualified Data.Text.Lazy.Encoding hiding (decodeUtf8)

    -- * class and conversions

    class ConvertibleStrings a b where
        convertString :: a -> b

    cs :: ConvertibleStrings a b => a -> b
    cs :: forall a b. ConvertibleStrings a b => a -> b
    cs = a -> b
    forall a b. ConvertibleStrings a b => a -> b
    convertString

    #if !MIN_VERSION_base(4,5,0)
    (<>) :: Monoid s => s -> s -> s
    (<>) = mappend
    #endif

    -- * type synonyms

    type StrictByteString = Data.ByteString.ByteString
    type SBS              = Data.ByteString.ByteString

    type LazyByteString = Data.ByteString.Lazy.ByteString
    type LBS            = Data.ByteString.Lazy.ByteString

    type StrictText = Data.Text.Text
    type ST         = Data.Text.Text

    type LazyText = Data.Text.Lazy.Text
    type LT       = Data.Text.Lazy.Text

    -- instances
    -- ---------

    -- from String

    instance ConvertibleStrings String String where
        convertString :: String -> String
    convertString = String -> String
    forall a. a -> a
    id

    instance ConvertibleStrings String StrictByteString where
        convertString :: String -> StrictByteString
    convertString = String -> StrictByteString
    Data.ByteString.UTF8.fromString

    instance ConvertibleStrings String LazyByteString where
        convertString :: String -> LazyByteString
    convertString = String -> LazyByteString
    Data.ByteString.Lazy.UTF8.fromString

    instance ConvertibleStrings String StrictText where
        convertString :: String -> StrictText
    convertString = String -> StrictText
    Data.Text.pack

    instance ConvertibleStrings String LazyText where
        convertString :: String -> LazyText
    convertString = String -> LazyText
    Data.Text.Lazy.pack

    -- from StrictByteString

    instance ConvertibleStrings StrictByteString StrictByteString where
        convertString :: StrictByteString -> StrictByteString
    convertString = StrictByteString -> StrictByteString
    forall a. a -> a
    id

    instance ConvertibleStrings StrictByteString String where
        convertString :: StrictByteString -> String
    convertString = StrictByteString -> String
    Data.ByteString.UTF8.toString

    instance ConvertibleStrings StrictByteString LazyByteString where
        convertString :: StrictByteString -> LazyByteString
    convertString = [StrictByteString] -> LazyByteString
    Data.ByteString.Lazy.fromChunks ([StrictByteString] -> LazyByteString)
    -> (StrictByteString -> [StrictByteString])
    -> StrictByteString
    -> LazyByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . StrictByteString -> [StrictByteString]
    forall a. a -> [a]
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure

    instance ConvertibleStrings StrictByteString StrictText where
        convertString :: StrictByteString -> StrictText
    convertString = OnDecodeError -> StrictByteString -> StrictText
    Data.Text.Encoding.decodeUtf8With OnDecodeError
    Data.Text.Encoding.Error.lenientDecode

    instance ConvertibleStrings StrictByteString LazyText where
        convertString :: StrictByteString -> LazyText
    convertString =
            OnDecodeError -> LazyByteString -> LazyText
    Data.Text.Lazy.Encoding.decodeUtf8With OnDecodeError
    Data.Text.Encoding.Error.lenientDecode (LazyByteString -> LazyText)
    -> (StrictByteString -> LazyByteString)
    -> StrictByteString
    -> LazyText
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
            [StrictByteString] -> LazyByteString
    Data.ByteString.Lazy.fromChunks ([StrictByteString] -> LazyByteString)
    -> (StrictByteString -> [StrictByteString])
    -> StrictByteString
    -> LazyByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . StrictByteString -> [StrictByteString]
    forall a. a -> [a]
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure

    -- from LazyByteString

    instance ConvertibleStrings LazyByteString LazyByteString where
        convertString :: LazyByteString -> LazyByteString
    convertString = LazyByteString -> LazyByteString
    forall a. a -> a
    id

    instance ConvertibleStrings LazyByteString String where
        convertString :: LazyByteString -> String
    convertString = LazyByteString -> String
    Data.ByteString.Lazy.UTF8.toString

    instance ConvertibleStrings LazyByteString StrictByteString where
        convertString :: LazyByteString -> StrictByteString
    convertString = [StrictByteString] -> StrictByteString
    forall a. Monoid a => [a] -> a
    mconcat ([StrictByteString] -> StrictByteString)
    -> (LazyByteString -> [StrictByteString])
    -> LazyByteString
    -> StrictByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LazyByteString -> [StrictByteString]
    Data.ByteString.Lazy.toChunks

    instance ConvertibleStrings LazyByteString StrictText where
        convertString :: LazyByteString -> StrictText
    convertString =
            OnDecodeError -> StrictByteString -> StrictText
    Data.Text.Encoding.decodeUtf8With  OnDecodeError
    Data.Text.Encoding.Error.lenientDecode (StrictByteString -> StrictText)
    -> (LazyByteString -> StrictByteString)
    -> LazyByteString
    -> StrictText
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
            [StrictByteString] -> StrictByteString
    forall a. Monoid a => [a] -> a
    mconcat ([StrictByteString] -> StrictByteString)
    -> (LazyByteString -> [StrictByteString])
    -> LazyByteString
    -> StrictByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LazyByteString -> [StrictByteString]
    Data.ByteString.Lazy.toChunks

    instance ConvertibleStrings LazyByteString LazyText where
        convertString :: LazyByteString -> LazyText
    convertString = OnDecodeError -> LazyByteString -> LazyText
    Data.Text.Lazy.Encoding.decodeUtf8With OnDecodeError
    Data.Text.Encoding.Error.lenientDecode

    -- from StrictText

    instance ConvertibleStrings StrictText StrictText where
        convertString :: StrictText -> StrictText
    convertString = StrictText -> StrictText
    forall a. a -> a
    id

    instance ConvertibleStrings StrictText String where
        convertString :: StrictText -> String
    convertString = StrictText -> String
    Data.Text.unpack

    instance ConvertibleStrings StrictText StrictByteString where
        convertString :: StrictText -> StrictByteString
    convertString = StrictText -> StrictByteString
    Data.Text.Encoding.encodeUtf8

    instance ConvertibleStrings StrictText LazyByteString where
        convertString :: StrictText -> LazyByteString
    convertString = [StrictByteString] -> LazyByteString
    Data.ByteString.Lazy.fromChunks ([StrictByteString] -> LazyByteString)
    -> (StrictText -> [StrictByteString])
    -> StrictText
    -> LazyByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . StrictByteString -> [StrictByteString]
    forall a. a -> [a]
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (StrictByteString -> [StrictByteString])
    -> (StrictText -> StrictByteString)
    -> StrictText
    -> [StrictByteString]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . StrictText -> StrictByteString
    Data.Text.Encoding.encodeUtf8

    instance ConvertibleStrings StrictText LazyText where
        convertString :: StrictText -> LazyText
    convertString = [StrictText] -> LazyText
    Data.Text.Lazy.fromChunks ([StrictText] -> LazyText)
    -> (StrictText -> [StrictText]) -> StrictText -> LazyText
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . StrictText -> [StrictText]
    forall a. a -> [a]
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure

    -- from LazyText

    instance ConvertibleStrings LazyText LazyText where
        convertString :: LazyText -> LazyText
    convertString = LazyText -> LazyText
    forall a. a -> a
    id

    instance ConvertibleStrings LazyText String where
        convertString :: LazyText -> String
    convertString = LazyText -> String
    Data.Text.Lazy.unpack

    instance ConvertibleStrings LazyText StrictByteString where
        convertString :: LazyText -> StrictByteString
    convertString =
            [StrictByteString] -> StrictByteString
    forall a. Monoid a => [a] -> a
    mconcat ([StrictByteString] -> StrictByteString)
    -> (LazyText -> [StrictByteString]) -> LazyText -> StrictByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LazyByteString -> [StrictByteString]
    Data.ByteString.Lazy.toChunks (LazyByteString -> [StrictByteString])
    -> (LazyText -> LazyByteString) -> LazyText -> [StrictByteString]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LazyText -> LazyByteString
    Data.Text.Lazy.Encoding.encodeUtf8

    instance ConvertibleStrings LazyText LazyByteString where
        convertString :: LazyText -> LazyByteString
    convertString = LazyText -> LazyByteString
    Data.Text.Lazy.Encoding.encodeUtf8

    instance ConvertibleStrings LazyText StrictText where
        convertString :: LazyText -> StrictText
    convertString = [StrictText] -> StrictText
    forall a. Monoid a => [a] -> a
    mconcat ([StrictText] -> StrictText)
    -> (LazyText -> [StrictText]) -> LazyText -> StrictText
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LazyText -> [StrictText]
    Data.Text.Lazy.toChunks