-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Builder for Text and ByteString based on linear types -- -- Strict Text and ByteString builder, which hides mutable buffer behind -- linear types and takes amortized linear time. @package text-builder-linear @version 0.1.1 -- | Low-level routines for Buffer manipulations. module Data.Text.Builder.Linear.Core -- | Internally Buffer is a mutable buffer. If a client gets hold of -- a variable of type Buffer, they'd be able to pass a mutable -- buffer to concurrent threads. That's why API below is carefully -- designed to prevent such possibility: clients always work with linear -- functions BufferBuffer instead and run them on an -- empty Buffer to extract results. -- -- In terms of linear-base Buffer is -- Consumable (see consumeBuffer) and -- Dupable (see dupBuffer), but not -- Movable. -- --
--   >>> :set -XOverloadedStrings -XLinearTypes
--   
--   >>> import Data.Text.Builder.Linear.Buffer
--   
--   >>> runBuffer (\b -> '!' .<| "foo" <| (b |> "bar" |>. '.'))
--   "!foobar."
--   
-- -- Remember: this is a strict builder, so on contrary to -- Data.Text.Lazy.Builder for optimal performance you should use -- strict left folds instead of lazy right ones. -- -- Buffer is an unlifted datatype, so you can put it into an -- unboxed tuple (# ..., ... #), but not into (..., -- ...). data Buffer :: TYPE ('BoxedRep 'Unlifted) -- | Run a linear function on an empty Buffer, producing a strict -- Text. -- -- Be careful to write runBuffer (b -> ...) instead of -- runBuffer $ b -> ..., because current implementation of -- linear types lacks special support for ($). Another option is -- to enable {-# LANGUAGE BlockArguments #-} and write -- runBuffer b -> .... Alternatively, you can import -- ($) from linear-base. -- -- runBuffer is similar in spirit to mutable arrays API in -- Data.Array.Mutable.Linear, which provides functions -- like fromList ∷ [a] → (Vector -- aUr b) ⊸ Ur b. -- Here the initial buffer is always empty and b is Text. -- Since Text is Movable, Text and -- Ur Text are equivalent. runBuffer :: (Buffer %1 -> Buffer) %1 -> Text -- | Same as runBuffer, but returning a UTF-8 encoded strict -- ByteString. runBufferBS :: (Buffer %1 -> Buffer) %1 -> ByteString -- | Duplicate builder. Feel free to process results in parallel threads. -- Similar to Dupable from linear-base. -- -- It is a bit tricky to use because of current limitations of -- linear types with regards to let and where. E. g., -- one cannot write -- --
--   let (# b1, b2 #) = dupBuffer b in ("foo" <| b1) >< (b2 |> "bar")
--   
-- -- Instead write: -- --
--   >>> :set -XOverloadedStrings -XLinearTypes -XUnboxedTuples
--   
--   >>> import Data.Text.Builder.Linear.Buffer
--   
--   >>> runBuffer (\b -> (\(# b1, b2 #) -> ("foo" <| b1) >< (b2 |> "bar")) (dupBuffer b))
--   "foobar"
--   
-- -- Note the unboxed tuple: Buffer is an unlifted datatype, so it -- cannot be put into (..., ...). dupBuffer :: Buffer %1 -> (# Buffer, Buffer #) -- | Consume buffer linearly, similar to Consumable from -- linear-base. consumeBuffer :: Buffer %1 -> () -- | Erase buffer's content, replacing it with an empty Text. eraseBuffer :: Buffer %1 -> Buffer -- | Return buffer's size in bytes (not in Chars). This could -- be useful to implement a lazy builder atop of a strict one. byteSizeOfBuffer :: Buffer %1 -> (# Buffer, Word #) -- | Return buffer's length in Chars (not in bytes). This could be -- useful to implement dropEndBuffer and takeEndBuffer, -- e. g., -- --
--   import Data.Unrestricted.Linear
--   
--   dropEndBuffer :: Word -> Buffer %1 -> Buffer
--   dropEndBuffer n buf =
--     ((# buf', len #) -> case move len of Ur len' -> takeBuffer (len' - n) buf')
--       (lengthOfBuffer buf)
--   
lengthOfBuffer :: Buffer %1 -> (# Buffer, Word #) -- | Slice Buffer by dropping given number of Chars. dropBuffer :: Word -> Buffer %1 -> Buffer -- | Slice Buffer by taking given number of Chars. takeBuffer :: Word -> Buffer %1 -> Buffer -- | Low-level routine to append data of unknown size to a Buffer. appendBounded :: Int -> (forall s. MArray s -> Int -> ST s Int) -> Buffer %1 -> Buffer -- | Low-level routine to append data of known size to a Buffer. appendExact :: Int -> (forall s. MArray s -> Int -> ST s ()) -> Buffer %1 -> Buffer -- | Low-level routine to prepend data of unknown size to a Buffer. prependBounded :: Int -> (forall s. MArray s -> Int -> ST s Int) -> (forall s. MArray s -> Int -> ST s Int) -> Buffer %1 -> Buffer -- | Low-level routine to append data of unknown size to a Buffer. prependExact :: Int -> (forall s. MArray s -> Int -> ST s ()) -> Buffer %1 -> Buffer -- | Concatenate two Buffers, potentially mutating both of them. -- -- You likely need to use dupBuffer to get hold on two builders at -- once: -- --
--   >>> :set -XOverloadedStrings -XLinearTypes -XUnboxedTuples
--   
--   >>> import Data.Text.Builder.Linear.Buffer
--   
--   >>> runBuffer (\b -> (\(# b1, b2 #) -> ("foo" <| b1) >< (b2 |> "bar")) (dupBuffer b))
--   "foobar"
--   
(><) :: Buffer %1 -> Buffer %1 -> Buffer infix 6 >< -- | Buffer for strict Text, based on linear types. module Data.Text.Builder.Linear.Buffer -- | Internally Buffer is a mutable buffer. If a client gets hold of -- a variable of type Buffer, they'd be able to pass a mutable -- buffer to concurrent threads. That's why API below is carefully -- designed to prevent such possibility: clients always work with linear -- functions BufferBuffer instead and run them on an -- empty Buffer to extract results. -- -- In terms of linear-base Buffer is -- Consumable (see consumeBuffer) and -- Dupable (see dupBuffer), but not -- Movable. -- --
--   >>> :set -XOverloadedStrings -XLinearTypes
--   
--   >>> import Data.Text.Builder.Linear.Buffer
--   
--   >>> runBuffer (\b -> '!' .<| "foo" <| (b |> "bar" |>. '.'))
--   "!foobar."
--   
-- -- Remember: this is a strict builder, so on contrary to -- Data.Text.Lazy.Builder for optimal performance you should use -- strict left folds instead of lazy right ones. -- -- Buffer is an unlifted datatype, so you can put it into an -- unboxed tuple (# ..., ... #), but not into (..., -- ...). data Buffer :: TYPE ('BoxedRep 'Unlifted) -- | Run a linear function on an empty Buffer, producing a strict -- Text. -- -- Be careful to write runBuffer (b -> ...) instead of -- runBuffer $ b -> ..., because current implementation of -- linear types lacks special support for ($). Another option is -- to enable {-# LANGUAGE BlockArguments #-} and write -- runBuffer b -> .... Alternatively, you can import -- ($) from linear-base. -- -- runBuffer is similar in spirit to mutable arrays API in -- Data.Array.Mutable.Linear, which provides functions -- like fromList ∷ [a] → (Vector -- aUr b) ⊸ Ur b. -- Here the initial buffer is always empty and b is Text. -- Since Text is Movable, Text and -- Ur Text are equivalent. runBuffer :: (Buffer %1 -> Buffer) %1 -> Text -- | Same as runBuffer, but returning a UTF-8 encoded strict -- ByteString. runBufferBS :: (Buffer %1 -> Buffer) %1 -> ByteString -- | Duplicate builder. Feel free to process results in parallel threads. -- Similar to Dupable from linear-base. -- -- It is a bit tricky to use because of current limitations of -- linear types with regards to let and where. E. g., -- one cannot write -- --
--   let (# b1, b2 #) = dupBuffer b in ("foo" <| b1) >< (b2 |> "bar")
--   
-- -- Instead write: -- --
--   >>> :set -XOverloadedStrings -XLinearTypes -XUnboxedTuples
--   
--   >>> import Data.Text.Builder.Linear.Buffer
--   
--   >>> runBuffer (\b -> (\(# b1, b2 #) -> ("foo" <| b1) >< (b2 |> "bar")) (dupBuffer b))
--   "foobar"
--   
-- -- Note the unboxed tuple: Buffer is an unlifted datatype, so it -- cannot be put into (..., ...). dupBuffer :: Buffer %1 -> (# Buffer, Buffer #) -- | Consume buffer linearly, similar to Consumable from -- linear-base. consumeBuffer :: Buffer %1 -> () -- | Erase buffer's content, replacing it with an empty Text. eraseBuffer :: Buffer %1 -> Buffer -- | This is just a normal foldl', but with a linear arrow and -- unlifted accumulator. foldlIntoBuffer :: forall a. (Buffer %1 -> a -> Buffer) -> Buffer %1 -> [a] -> Buffer -- | Append Text suffix to a Buffer by mutating it. If a -- suffix is statically known, consider using (|>#) for optimal -- performance. -- --
--   >>> :set -XOverloadedStrings -XLinearTypes
--   
--   >>> runBuffer (\b -> b |> "foo" |> "bar")
--   "foobar"
--   
(|>) :: Buffer %1 -> Text -> Buffer infixl 6 |> -- | Append Char to a Buffer by mutating it. -- --
--   >>> :set -XLinearTypes
--   
--   >>> runBuffer (\b -> b |>. 'q' |>. 'w')
--   "qw"
--   
-- -- In contrast to singleton, it's a responsibility of the caller -- to sanitize surrogate code points with safe. (|>.) :: Buffer %1 -> Char -> Buffer infixl 6 |>. -- | Append a null-terminated UTF-8 string to a Buffer by mutating -- it. E. g., -- --
--   >>> :set -XOverloadedStrings -XLinearTypes -XMagicHash
--   
--   >>> runBuffer (\b -> b |># "foo"# |># "bar"#)
--   "foobar"
--   
-- -- The literal string must not contain zero bytes \0 and must be -- a valid UTF-8, these conditions are not checked. -- -- Note the inconsistency in naming: unfortunately, GHC parser does not -- allow for #<|. (|>#) :: Buffer %1 -> Addr# -> Buffer infixl 6 |># -- | Prepend Text prefix to a Buffer by mutating it. If a -- prefix is statically known, consider using (<|#) for optimal -- performance. -- --
--   >>> :set -XOverloadedStrings -XLinearTypes
--   
--   >>> runBuffer (\b -> "foo" <| "bar" <| b)
--   "foobar"
--   
(<|) :: Text -> Buffer %1 -> Buffer infixr 6 <| -- | Prepend Char to a Buffer by mutating it. -- --
--   >>> :set -XLinearTypes
--   
--   >>> runBuffer (\b -> 'q' .<| 'w' .<| b)
--   "qw"
--   
-- -- In contrast to singleton, it's a responsibility of the caller -- to sanitize surrogate code points with safe. (.<|) :: Char -> Buffer %1 -> Buffer infixr 6 .<| -- | Prepend a null-terminated UTF-8 string to a Buffer by mutating -- it. E. g., -- --
--   >>> :set -XOverloadedStrings -XLinearTypes -XMagicHash
--   
--   >>> runBuffer (\b -> "foo"# <|# "bar"# <|# b)
--   "foobar"
--   
-- -- The literal string must not contain zero bytes \0 and must be -- a valid UTF-8, these conditions are not checked. (<|#) :: Addr# -> Buffer %1 -> Buffer infixr 6 <|# -- | Concatenate two Buffers, potentially mutating both of them. -- -- You likely need to use dupBuffer to get hold on two builders at -- once: -- --
--   >>> :set -XOverloadedStrings -XLinearTypes -XUnboxedTuples
--   
--   >>> import Data.Text.Builder.Linear.Buffer
--   
--   >>> runBuffer (\b -> (\(# b1, b2 #) -> ("foo" <| b1) >< (b2 |> "bar")) (dupBuffer b))
--   "foobar"
--   
(><) :: Buffer %1 -> Buffer %1 -> Buffer infix 6 >< -- | Append decimal number. (|>$) :: (Integral a, FiniteBits a) => Buffer %1 -> a -> Buffer infixl 6 |>$ -- | Prepend decimal number. ($<|) :: (Integral a, FiniteBits a) => a -> Buffer %1 -> Buffer infixr 6 $<| -- | Append double. (|>%) :: Buffer %1 -> Double -> Buffer infixl 6 |>% -- | Prepend double (%<|) :: Double -> Buffer %1 -> Buffer infixr 6 %<| -- | Append hexadecimal number. (|>&) :: (Integral a, FiniteBits a) => Buffer %1 -> a -> Buffer infixl 6 |>& -- | Prepend hexadecimal number. (&<|) :: (Integral a, FiniteBits a) => a -> Buffer %1 -> Buffer infixr 6 &<| -- | Append given number of spaces. (|>…) :: Buffer %1 -> Word -> Buffer infixr 6 |>… -- | Prepend given number of spaces. (…<|) :: Word -> Buffer %1 -> Buffer infixr 6 …<| -- | Builder for strict Text and ByteString, based on linear -- types. It consistently outperforms Data.Text.Lazy.Builder from -- text as well as a strict builder from text-builder, -- and scales better. module Data.Text.Builder.Linear -- | Thin wrapper over Buffer with a handy Semigroup -- instance. -- --
--   >>> :set -XOverloadedStrings -XMagicHash
--   
--   >>> fromText "foo" <> fromChar '_' <> fromAddr "bar"#
--   "foo_bar"
--   
-- -- Remember: this is a strict builder, so on contrary to -- Data.Text.Lazy.Builder for optimal performance you should use -- strict left folds instead of lazy right ones. -- -- Note that (similar to other builders) concatenation of Builders -- allocates thunks. This is to a certain extent mitigated by aggressive -- inlining, but it is faster to use Buffer directly. newtype Builder Builder :: (Buffer %1 -> Buffer) -> Builder [unBuilder] :: Builder -> Buffer %1 -> Buffer -- | Run Builder computation on an empty Buffer, returning -- strict Text. -- --
--   >>> :set -XOverloadedStrings -XMagicHash
--   
--   >>> runBuilder (fromText "foo" <> fromChar '_' <> fromAddr "bar"#)
--   "foo_bar"
--   
-- -- This function has a polymorphic arrow and thus can be used both in -- usual and linear contexts. runBuilder :: forall m. Builder %m -> Text -- | Same as runBuilder, but returning a UTF-8 encoded strict -- ByteString. runBuilderBS :: forall m. Builder %m -> ByteString -- | Create Builder, containing a given Text. -- --
--   >>> :set -XOverloadedStrings
--   
--   >>> fromText "foo" <> fromText "bar"
--   "foobar"
--   
fromText :: Text -> Builder -- | Create Builder, containing a given Char. -- --
--   >>> fromChar 'x' <> fromChar 'y'
--   "xy"
--   
-- -- In contrast to singleton, it's a responsibility of the caller -- to sanitize surrogate code points with safe. fromChar :: Char -> Builder -- | Create Builder, containing a null-terminated UTF-8 string, -- specified by Addr#. -- --
--   >>> :set -XMagicHash
--   
--   >>> fromAddr "foo"# <> fromAddr "bar"#
--   "foobar"
--   
-- -- The literal string must not contain zero bytes \0 and must be -- a valid UTF-8, these conditions are not checked. fromAddr :: Addr# -> Builder -- | Create Builder, containing decimal representation of a given -- integer. -- --
--   >>> fromChar 'x' <> fromDec (123 :: Int)
--   "x123"
--   
fromDec :: (Integral a, FiniteBits a) => a -> Builder -- | Create Builder, containing hexadecimal representation of a -- given integer. -- --
--   >>> :set -XMagicHash
--   
--   >>> fromAddr "0x"# <> fromHex (0x123def :: Int)
--   "0x123def"
--   
fromHex :: (Integral a, FiniteBits a) => a -> Builder -- | Create Builder, containing decimal representation of a given -- Double. -- --
--   >>> :set -XMagicHash
--   
--   >>> fromAddr "pi="# <> fromDouble pi
--   "pi=3.141592653589793"
--   
fromDouble :: Double -> Builder instance GHC.Show.Show Data.Text.Builder.Linear.Builder instance GHC.Base.Semigroup Data.Text.Builder.Linear.Builder instance GHC.Base.Monoid Data.Text.Builder.Linear.Builder instance Data.String.IsString Data.Text.Builder.Linear.Builder