buildable (empty) → 0.1.0.0
raw patch · 4 files changed
+888/−0 lines, 4 filesdep +basedep +bytestringdep +containerssetup-changed
Dependencies added: base, bytestring, containers, dlist, text
Files
- LICENSE +20/−0
- Setup.hs +2/−0
- buildable.cabal +55/−0
- src/Data/Buildable.hs +811/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2014 Ivan Lazar Miljenovic++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ buildable.cabal view
@@ -0,0 +1,55 @@+name: buildable+version: 0.1.0.0+synopsis: Typeclass for builders of linear data structures+description: {+Various linear data structures can be expensive to construct in a+repetitive fashion. For example, to append a single value to the end+of a list is @O(n)@, and as such doing so repeatedly is recommended+against.+.+As such, to efficiently construct such structures we have the notion+of a /builder/. This can be used to more efficiently prepend and+append values, and at the end we \"run\" the builder to construct the+overall value.+.+This module provides an abstraction over various builders for specific+data structures. It also aims to minimise the number of functions+required to add various values to the builder by using a typeclass and+newtype wrappers.+.+To construct a value from it's builder:+.+ 1. Start with either @'mempty'@ for an empty 'Builder', or if you+ have an initial value use @'fromValue'@.+.+ 2. Add initial values to the front or back using 'prepend' \/ '<|'+ or 'append' \/ '|>' respectively.+.+ 3. Once you've finished constructing your builder, create your+ final value with 'build'.+.+/Note/: all instances are defined for both strict and lazy+@ByteString@ and @Text@ values.+}++license: MIT+license-file: LICENSE+author: Ivan Lazar Miljenovic+maintainer: Ivan.Miljenovic@gmail.com+-- copyright:+category: Data+build-type: Simple+-- extra-source-files:+cabal-version: >=1.10++library+ exposed-modules: Data.Buildable+ -- other-modules:+ -- other-extensions:+ build-depends: base >=4.6 && <4.7+ , bytestring >= 0.10.0.0 && < 0.11+ , containers == 0.5.*+ , dlist >= 0.5 && < 0.8+ , text >= 0.11.3.0 && < 1.12+ hs-source-dirs: src+ default-language: Haskell2010
+ src/Data/Buildable.hs view
@@ -0,0 +1,811 @@+{-# LANGUAGE ConstraintKinds, FlexibleContexts, FlexibleInstances,+ GeneralizedNewtypeDeriving, MultiParamTypeClasses,+ OverlappingInstances, TypeFamilies, UndecidableInstances #-}++{- |+ Module : Data.Buildable+ Description : Builders for linear data structures+ Copyright : (c) Ivan Lazar Miljenovic+ License : 3-Clause BSD-style+ Maintainer : Ivan.Miljenovic@gmail.com++Various linear data structures can be expensive to construct in a+repetitive fashion. For example, to append a single value to the end+of a list is @O(n)@, and as such doing so repeatedly is recommended+against.++As such, to efficiently construct such structures we have the notion+of a /builder/. This can be used to more efficiently prepend and+append values, and at the end we \"run\" the builder to construct the+overall value.++This module provides an abstraction over various builders for specific+data structures. It also aims to minimise the number of functions+required to add various values to the builder by using a typeclass and+newtype wrappers.++To construct a value from it's builder:++ 1. Start with either @'mempty'@ for an empty 'Builder', or if you+ have an initial value use @'fromValue'@.++ 2. Add initial values to the front or back using 'prepend' \/ '<|'+ or 'append' \/ '|>' respectively.++ 3. Once you've finished constructing your builder, create your+ final value with 'build'.++/Note/: all instances are defined for both strict and lazy+@ByteString@ and @Text@ values.++ -}+module Data.Buildable+ ( -- * Typeclasses+ Buildable (..)+ , BuildFrom (..)+ , CanBuildFrom+ , singleton+ , (<|)+ , (|>)+ -- * Chunked builder+ -- $chunked+ , Chunked (..)+ , ChunkedBuilder (..)++ -- * ByteString Builders+ -- $bytestring++ -- ** Numeric wrappers+ -- $numeric+ , BigEndian (..)+ , LittleEndian (..)+ , Dec (..)+ , Hex (..)+ , HexFixed (..)+ -- ** Textual wrappers+ -- $textual+ , Char7 (..)+ , Char8 (..)+ , Utf8 (..)+ , Utf16 (..)+ , Utf32 (..)++ -- * Text Builders+ -- $text+ ) where++import Data.Monoid (Monoid (..), (<>))+import Data.String (IsString (..))++import qualified Data.DList as DL++import qualified Data.ByteString as SB+import qualified Data.ByteString.Lazy as LB+import qualified Data.ByteString.Lazy.Builder as B+import qualified Data.ByteString.Lazy.Builder.ASCII as B+import Data.Int+import Data.Word++import qualified Data.Text as ST+import qualified Data.Text.Encoding as ST+import qualified Data.Text.Lazy as LT+import qualified Data.Text.Lazy.Builder as T+import qualified Data.Text.Lazy.Encoding as LT++import qualified Data.Sequence as S++-- -----------------------------------------------------------------------------++-- | A linear data structure @a@ is buildable if we can prepend and+-- append both values of the data structure in question and its+-- constituent elements to the builder.+class (BuildFrom (Builder a) a, BuildFrom (Builder a) (Unit a))+ => Buildable a where++ -- | The individual elements.+ type Unit a++ type Builder a++ -- | Build the actual data structure.+ build :: Builder a -> a++-- | @CanBuildFrom b a@ states that we can build a value of type @b@+-- with values of type @a@.+type CanBuildFrom b a = (Buildable b, BuildFrom (Builder b) a)++singleton :: (CanBuildFrom b a) => a -> b+singleton = build . fromValue+{-# INLINE [1] singleton #-}+-- The [1] is to make sure the rule fires.++{-# RULES++"singleton/sametype" forall b. singleton b = b++ #-}++-- -----------------------------------------------------------------------------++-- | Which values can be built from other values?+--+-- Minimal complete definition:+--+-- * @fromValue@+class (Monoid b) => BuildFrom b a where++ -- | Create a builder from an initial value.+ fromValue :: a -> b++ -- | Add a value to the front.+ prepend :: a -> b -> b+ prepend a b = fromValue a <> b++ -- | Add a value to the end.+ append :: b -> a -> b+ append b a = b <> fromValue a++-- | An alias for 'prepend'.+--+-- Mnemonic: the arrow points to the new value.+(<|) :: (BuildFrom b a) => a -> b -> b+(<|) = prepend++infixr 4 <|++-- | An alias for 'append'.+--+-- Mnemonic: the arrow points to the new value.+(|>) :: (BuildFrom b a) => b -> a -> b+(|>) = append++infixl 5 |>+-- Have this bind tighter than <| because if builders have a+-- preference, it's that appends should be preferred (thus take care+-- of any appends first before prepending as it might prove cheaper).++-- -----------------------------------------------------------------------------+-- Lists++instance Buildable [a] where+ type Unit [a] = a+ type Builder [a] = DL.DList a++ build = DL.toList++instance BuildFrom [a] a where+ fromValue = (: [])++ prepend = (:)++instance BuildFrom (DL.DList a) [a] where+ fromValue = DL.fromList++instance BuildFrom (DL.DList a) a where+ fromValue = DL.singleton++ prepend = DL.cons++ append = DL.snoc++instance BuildFrom (DL.DList [a]) a where+ fromValue = DL.singleton . (: [])++ prepend = DL.cons . (: [])++ append b = DL.snoc b . (: [])++-- -----------------------------------------------------------------------------+-- Chunked builder++{- $chunked++For either testing purposes or some other reason, rather than actually+creating an overall value you may actually want a list of a+'Buildable' type.++The 'Chunked' type allows you to efficiently create a list of such+values by converting every provided value into the specified type.++-}++-- | An explicit chunkified representation of a Builder. If we have a+-- polymorphic expression @buildValue@ that can be used to build+-- something of type @b@, then the following are equivalent:+--+-- > 'build' buildValue == mconcat . unChunk $ build buildValue+newtype Chunked a = Chunks { unChunk :: [a]}+ deriving (Eq, Ord, Show, Read, Monoid, Functor)++-- | You probably won't actually need to use this type; it's defined+-- solely to be the 'Builder' for 'Chunked'.+newtype ChunkedBuilder a = CB { unCB :: DL.DList a }+ deriving (Monoid, Functor)++instance (Buildable b) => Buildable (Chunked b) where+ type Unit (Chunked b) = b+ type Builder (Chunked b) = ChunkedBuilder b++ build = Chunks . DL.toList . unCB++instance (Buildable b) => BuildFrom (ChunkedBuilder b) (Chunked b) where+ fromValue = CB . DL.fromList . unChunk++instance (CanBuildFrom b a) => BuildFrom (ChunkedBuilder b) a where+ fromValue = CB . DL.singleton . singleton++ prepend a (CB b) = CB (singleton a `DL.cons` b)++ append (CB b) a = CB (b `DL.snoc` singleton a)++-- -----------------------------------------------------------------------------+-- ByteStrings++{- $bytestring++There are various ways that numeric and textual types can be built+into part of a @ByteString@ (be it strict or lazy). To be able to+choose between these, various wrapper types have been defined.++What you can add to the @ByteString@ Builder:++ * Strict and lazy ByteStrings.++ * Numeric types, though most require a wrapper to disambiguate+ /how/ to add it (see below)/++ * 'Char' and 'String' and both strict and lazy @Text@ values after+ choosing an appropriate encoding (see below for wrapper types).++-}++-- | Strict ByteStrings. This instance goes via lazy ByteStrings, and+-- as such they should be preferred.+instance Buildable SB.ByteString where+ type Unit SB.ByteString = Word8+ type Builder SB.ByteString = B.Builder++ build = LB.toStrict . B.toLazyByteString++{-# RULES "unbuild/SB.ByteString" forall b. LB.toStrict (B.toLazyByteString (B.byteString b)) = b #-}++-- | Lazy ByteStrings. This instance should be preferred over the one+-- for strict ByteStrings.+instance Buildable LB.ByteString where+ type Unit LB.ByteString = Word8+ type Builder LB.ByteString = B.Builder++ build = B.toLazyByteString++{-# RULES "unbuild/LB.ByteString" forall b. B.toLazyByteString (B.lazyByteString b) = b #-}++{- $numeric++Apart from 'Word8' and 'Int8', all numeric types need to be specified+whether they should be encoded using 'BigEndian' or 'LittleEndian'+format (with the exception of decimal representation using 'Dec').++All wrappers derive the various numeric type classes so that you can+still perform various calculations on them.++-}++-- | Explicitly state that a number should be encoded in big-endian+-- format.+newtype BigEndian a = BE { unBE :: a }+ deriving ( Eq, Ord, Show, Read, Bounded, Enum+ , Num, Integral, Real, RealFloat, RealFrac, Floating, Fractional)++-- | Explicitly state that a number should be encoded in little-endian+-- format.+newtype LittleEndian a = LE { unLE :: a }+ deriving ( Eq, Ord, Show, Read, Bounded, Enum+ , Num, Integral, Real, RealFloat, RealFrac, Floating, Fractional)++-- | Encode a number as its decimal representation with ASCII-encoded+-- characters.+newtype Dec a = Dec { unDec :: a }+ deriving ( Eq, Ord, Show, Read, Bounded, Enum+ , Num, Integral, Real, RealFloat, RealFrac, Floating, Fractional)++-- | Encode a number as its hexadecimal representation with+-- ASCII-encoded (lower-case) characters using the shortest possible+-- representation. For fixed-width encoding use 'HexFixed' instead.+newtype Hex a = Hex { unHex :: a }+ deriving ( Eq, Ord, Show, Read, Bounded, Enum+ , Num, Integral, Real, RealFloat, RealFrac, Floating, Fractional)++-- | Encode a number as its hexadecimal representation with+-- ASCII-encoded (lower-case) characters using a fixed number of+-- hexadecimal digits. For shortest-width encoding use 'Hex'+-- instead.+newtype HexFixed a = HexFixed { unHexFixed :: a }+ deriving ( Eq, Ord, Show, Read, Bounded, Enum+ , Num, Integral, Real, RealFloat, RealFrac, Floating, Fractional)++instance BuildFrom B.Builder SB.ByteString where+ fromValue = B.byteString++instance BuildFrom B.Builder (HexFixed SB.ByteString) where+ fromValue = B.byteStringHexFixed . unHexFixed++instance BuildFrom B.Builder LB.ByteString where+ fromValue = B.lazyByteString++instance BuildFrom B.Builder (HexFixed LB.ByteString) where+ fromValue = B.lazyByteStringHexFixed . unHexFixed++instance BuildFrom B.Builder Word8 where+ fromValue = B.word8++instance BuildFrom B.Builder (Dec Word8) where+ fromValue = B.word8Dec . unDec++instance BuildFrom B.Builder (Hex Word8) where+ fromValue = B.word8Hex . unHex++-- | Uses 2 nibbles/hexadecimal digits.+instance BuildFrom B.Builder (HexFixed Word8) where+ fromValue = B.word8HexFixed . unHexFixed++instance BuildFrom B.Builder Int8 where+ fromValue = B.int8++instance BuildFrom B.Builder (Dec Int8) where+ fromValue = B.int8Dec . unDec++-- | Uses 2 nibbles/hexadecimal digits.+instance BuildFrom B.Builder (HexFixed Int8) where+ fromValue = B.int8HexFixed . unHexFixed++instance BuildFrom B.Builder (BigEndian Double) where+ fromValue = B.doubleBE . unBE++instance BuildFrom B.Builder (LittleEndian Double) where+ fromValue = B.doubleLE . unLE++-- | Currently slow.+instance BuildFrom B.Builder (Dec Double) where+ fromValue = B.doubleDec . unDec++-- | Uses 16 nibbles/hexadecimal digits.+instance BuildFrom B.Builder (HexFixed Double) where+ fromValue = B.doubleHexFixed . unHexFixed++instance BuildFrom B.Builder (BigEndian Float) where+ fromValue = B.floatBE . unBE++instance BuildFrom B.Builder (LittleEndian Float) where+ fromValue = B.floatLE . unLE++-- | Currently slow.+instance BuildFrom B.Builder (Dec Float) where+ fromValue = B.floatDec . unDec++-- | Uses 8 nibbles/hexadecimal digits.+instance BuildFrom B.Builder (HexFixed Float) where+ fromValue = B.floatHexFixed . unHexFixed++instance BuildFrom B.Builder (BigEndian Int16) where+ fromValue = B.int16BE . unBE++instance BuildFrom B.Builder (LittleEndian Int16) where+ fromValue = B.int16LE . unLE++instance BuildFrom B.Builder (Dec Int16) where+ fromValue = B.int16Dec . unDec++-- | Uses 4 nibbles/hexadecimal digits.+instance BuildFrom B.Builder (HexFixed Int16) where+ fromValue = B.int16HexFixed . unHexFixed++instance BuildFrom B.Builder (BigEndian Int32) where+ fromValue = B.int32BE . unBE++instance BuildFrom B.Builder (LittleEndian Int32) where+ fromValue = B.int32LE . unLE++instance BuildFrom B.Builder (Dec Int32) where+ fromValue = B.int32Dec . unDec++-- | Uses 8 nibbles/hexadecimal digits.+instance BuildFrom B.Builder (HexFixed Int32) where+ fromValue = B.int32HexFixed . unHexFixed++instance BuildFrom B.Builder (BigEndian Int64) where+ fromValue = B.int64BE . unBE++instance BuildFrom B.Builder (LittleEndian Int64) where+ fromValue = B.int64LE . unLE++instance BuildFrom B.Builder (Dec Int64) where+ fromValue = B.int64Dec . unDec++-- | Uses 16 nibbles/hexadecimal digits.+instance BuildFrom B.Builder (HexFixed Int64) where+ fromValue = B.int64HexFixed . unHexFixed++instance BuildFrom B.Builder (Dec Int) where+ fromValue = B.intDec . unDec++instance BuildFrom B.Builder (Dec Integer) where+ fromValue = B.integerDec . unDec++instance BuildFrom B.Builder (BigEndian Word16) where+ fromValue = B.word16BE . unBE++instance BuildFrom B.Builder (LittleEndian Word16) where+ fromValue = B.word16LE . unLE++instance BuildFrom B.Builder (Dec Word16) where+ fromValue = B.word16Dec . unDec++instance BuildFrom B.Builder (Hex Word16) where+ fromValue = B.word16Hex . unHex++-- | Uses 4 nibbles/hexadecimal digits.+instance BuildFrom B.Builder (HexFixed Word16) where+ fromValue = B.word16HexFixed . unHexFixed++instance BuildFrom B.Builder (BigEndian Word32) where+ fromValue = B.word32BE . unBE++instance BuildFrom B.Builder (LittleEndian Word32) where+ fromValue = B.word32LE . unLE++instance BuildFrom B.Builder (Dec Word32) where+ fromValue = B.word32Dec . unDec++instance BuildFrom B.Builder (Hex Word32) where+ fromValue = B.word32Hex . unHex++-- | Uses 8 nibbles/hexadecimal digits.+instance BuildFrom B.Builder (HexFixed Word32) where+ fromValue = B.word32HexFixed . unHexFixed++instance BuildFrom B.Builder (BigEndian Word64) where+ fromValue = B.word64BE . unBE++instance BuildFrom B.Builder (LittleEndian Word64) where+ fromValue = B.word64LE . unLE++instance BuildFrom B.Builder (Dec Word64) where+ fromValue = B.word64Dec . unDec++instance BuildFrom B.Builder (Hex Word64) where+ fromValue = B.word64Hex . unHex++-- | Uses 16 nibbles/hexadecimal digits.+instance BuildFrom B.Builder (HexFixed Word64) where+ fromValue = B.word64HexFixed . unHexFixed++instance BuildFrom B.Builder (Dec Word) where+ fromValue = B.wordDec . unDec++instance BuildFrom B.Builder (Hex Word) where+ fromValue = B.wordHex . unHex++{- $textual++There are various different encodings that can be used to encode+textual data as a series of binary digits. As such, it is necessary+to specify which encoding you want to use.++For 'Utf16' and 'Utf32' it is also necessary to specify whether you+want to use a 'BigEndian' or 'LittleEndian' format; the order of+newtype wrappers doesn't matter.++These are also used to encode a @ByteString@ into the 'Builder' for+@Text@ values (both strict and lazy).++-}++-- | Unicode codepoints are truncated to 7 bits and prefixed with a+-- leading 0. For the codepoints 0-127 this corresponds to the+-- ASCII encoding.+newtype Char7 a = Char7 { unChar7 :: a }+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++instance (IsString a) => IsString (Char7 a) where+ fromString = Char7 . fromString++-- | Unicode codepoints are truncated to 8 bits. For the codepoints+-- 0-255 this corresponds to the ISO/IEC 8859-1 (aka Latin-1)+-- encoding.+newtype Char8 a = Char8 { unChar8 :: a }+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++instance (IsString a) => IsString (Char8 a) where+ fromString = Char8 . fromString++-- | Encode a textual value using UTF-8.+newtype Utf8 a = Utf8 { unUtf8 :: a }+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++instance (IsString a) => IsString (Utf8 a) where+ fromString = Utf8 . fromString++-- | Encode a textual value using UTF-16.+--+-- Needs to be used with either 'BigEndian' or 'LittleEndian'.+newtype Utf16 a = Utf16 { unUtf16 :: a }+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++instance (IsString a) => IsString (Utf16 a) where+ fromString = Utf16 . fromString++-- | Encode a textual value using UTF-32.+--+-- Needs to be used with either 'BigEndian' or 'LittleEndian'.+newtype Utf32 a = Utf32 { unUtf32 :: a }+ deriving (Eq, Ord, Show, Read, Bounded, Enum)++instance (IsString a) => IsString (Utf32 a) where+ fromString = Utf32 . fromString++instance BuildFrom B.Builder (Char7 Char) where+ fromValue = B.char7 . unChar7++instance BuildFrom B.Builder (Char8 Char) where+ fromValue = B.char8 . unChar8++instance BuildFrom B.Builder (Utf8 Char) where+ fromValue = B.charUtf8 . unUtf8++instance BuildFrom B.Builder (Char7 String) where+ fromValue = B.string7 . unChar7++instance BuildFrom B.Builder (Char8 String) where+ fromValue = B.string8 . unChar8++instance BuildFrom B.Builder (Utf8 String) where+ fromValue = B.stringUtf8 . unUtf8++-- | For strict Text values; goes via a strict ByteString.+instance BuildFrom B.Builder (Utf8 ST.Text) where+ fromValue = B.byteString . ST.encodeUtf8 . unUtf8++-- | For strict Text values; goes via a strict ByteString. Equivalent+-- to the @Utf16 (BigEndian Text)@ instance.+instance BuildFrom B.Builder (BigEndian (Utf16 ST.Text)) where+ fromValue = B.byteString . ST.encodeUtf16BE . unUtf16 . unBE++-- | For strict Text values; goes via a strict ByteString. Equivalent+-- to the @BigEndian (Utf16 Text)@ instance.+instance BuildFrom B.Builder (Utf16 (BigEndian ST.Text)) where+ fromValue = B.byteString . ST.encodeUtf16BE . unBE . unUtf16++-- | For strict Text values; goes via a strict ByteString. Equivalent+-- to the @Utf16 (LittleEndian Text)@ instance.+instance BuildFrom B.Builder (LittleEndian (Utf16 ST.Text)) where+ fromValue = B.byteString . ST.encodeUtf16LE . unUtf16 . unLE++-- | For strict Text values; goes via a strict ByteString. Equivalent+-- to the @LittleEndian (Utf16 Text)@ instance.+instance BuildFrom B.Builder (Utf16 (LittleEndian ST.Text)) where+ fromValue = B.byteString . ST.encodeUtf16LE . unLE . unUtf16++-- | For strict Text values; goes via a strict ByteString. Equivalent+-- to the @Utf32 (BigEndian Text)@ instance.+instance BuildFrom B.Builder (BigEndian (Utf32 ST.Text)) where+ fromValue = B.byteString . ST.encodeUtf32BE . unUtf32 . unBE++-- | For strict Text values; goes via a strict ByteString. Equivalent+-- to the @BigEndian (Utf32 Text)@ instance.+instance BuildFrom B.Builder (Utf32 (BigEndian ST.Text)) where+ fromValue = B.byteString . ST.encodeUtf32BE . unBE . unUtf32++-- | For strict Text values; goes via a strict ByteString. Equivalent+-- to the @Utf32 (LittleEndian Text)@ instance.+instance BuildFrom B.Builder (LittleEndian (Utf32 ST.Text)) where+ fromValue = B.byteString . ST.encodeUtf32LE . unUtf32 . unLE++-- | For strict Text values; goes via a strict ByteString. Equivalent+-- to the @LittleEndian (Utf32 Text)@ instance.+instance BuildFrom B.Builder (Utf32 (LittleEndian ST.Text)) where+ fromValue = B.byteString . ST.encodeUtf32LE . unLE . unUtf32++-- | For lazy Text values; goes via a lazy ByteString.+instance BuildFrom B.Builder (Utf8 LT.Text) where+ fromValue = B.lazyByteString . LT.encodeUtf8 . unUtf8++-- | For lazy Text values; goes via a lazy ByteString. Equivalent+-- to the @Utf16 (BigEndian Text)@ instance.+instance BuildFrom B.Builder (BigEndian (Utf16 LT.Text)) where+ fromValue = B.lazyByteString . LT.encodeUtf16BE . unUtf16 . unBE++-- | For lazy Text values; goes via a lazy ByteString. Equivalent+-- to the @BigEndian (Utf16 Text)@ instance.+instance BuildFrom B.Builder (Utf16 (BigEndian LT.Text)) where+ fromValue = B.lazyByteString . LT.encodeUtf16BE . unBE . unUtf16++-- | For lazy Text values; goes via a lazy ByteString. Equivalent+-- to the @Utf16 (LittleEndian Text)@ instance.+instance BuildFrom B.Builder (LittleEndian (Utf16 LT.Text)) where+ fromValue = B.lazyByteString . LT.encodeUtf16LE . unUtf16 . unLE++-- | For lazy Text values; goes via a lazy ByteString. Equivalent+-- to the @LittleEndian (Utf16 Text)@ instance.+instance BuildFrom B.Builder (Utf16 (LittleEndian LT.Text)) where+ fromValue = B.lazyByteString . LT.encodeUtf16LE . unLE . unUtf16++-- | For lazy Text values; goes via a lazy ByteString. Equivalent+-- to the @Utf32 (BigEndian Text)@ instance.+instance BuildFrom B.Builder (BigEndian (Utf32 LT.Text)) where+ fromValue = B.lazyByteString . LT.encodeUtf32BE . unUtf32 . unBE++-- | For lazy Text values; goes via a lazy ByteString. Equivalent+-- to the @BigEndian (Utf32 Text)@ instance.+instance BuildFrom B.Builder (Utf32 (BigEndian LT.Text)) where+ fromValue = B.lazyByteString . LT.encodeUtf32BE . unBE . unUtf32++-- | For lazy Text values; goes via a lazy ByteString. Equivalent+-- to the @Utf32 (LittleEndian Text)@ instance.+instance BuildFrom B.Builder (LittleEndian (Utf32 LT.Text)) where+ fromValue = B.lazyByteString . LT.encodeUtf32LE . unUtf32 . unLE++-- | For lazy Text values; goes via a lazy ByteString. Equivalent+-- to the @LittleEndian (Utf32 Text)@ instance.+instance BuildFrom B.Builder (Utf32 (LittleEndian LT.Text)) where+ fromValue = B.lazyByteString . LT.encodeUtf32LE . unLE . unUtf32++-- -----------------------------------------------------------------------------+-- Text++{- $text++Both strict and lazy @Text@ values can be constructed via the text+Builder, though the latter is preferred.++Values that they can be built from:++ * Strict and lazy @Text@ values.++ * 'Char' and 'String' values directly.++ * Strict and lazy 'ByteStrings' after choosing an appropriate+ encoding.++-}++instance Buildable ST.Text where+ type Unit ST.Text = Char+ type Builder ST.Text = T.Builder++ build = LT.toStrict . T.toLazyText++instance Buildable LT.Text where+ type Unit LT.Text = Char+ type Builder LT.Text = T.Builder++ build = T.toLazyText++instance BuildFrom T.Builder ST.Text where+ fromValue = T.fromText++instance BuildFrom T.Builder LT.Text where+ fromValue = T.fromLazyText++instance BuildFrom T.Builder Char where+ fromValue = T.singleton++instance BuildFrom T.Builder String where+ fromValue = T.fromString++-- | For strict ByteStrings; goes via a strict Text.+instance BuildFrom T.Builder (Char8 SB.ByteString) where+ fromValue = T.fromText . ST.decodeLatin1 . unChar8++-- | For strict ByteStrings; goes via a strict Text.+instance BuildFrom T.Builder (Utf8 SB.ByteString) where+ fromValue = T.fromText . ST.decodeUtf8 . unUtf8++-- | For strict ByteStrings; goes via a strict Text. Equivalent to+-- the @Utf16 (BigEndian ByteString)@ instance.+instance BuildFrom T.Builder (BigEndian (Utf16 SB.ByteString)) where+ fromValue = T.fromText . ST.decodeUtf16BE . unUtf16 . unBE++-- | For strict ByteStrings; goes via a strict Text. Equivalent to+-- the @BigEndian (Utf16 ByteString)@ instance.+instance BuildFrom T.Builder (Utf16 (BigEndian SB.ByteString)) where+ fromValue = T.fromText . ST.decodeUtf16BE . unBE . unUtf16++-- | For strict ByteStrings; goes via a strict Text. Equivalent to+-- the @Utf16 (LittleEndian ByteString)@ instance.+instance BuildFrom T.Builder (LittleEndian (Utf16 SB.ByteString)) where+ fromValue = T.fromText . ST.decodeUtf16LE . unUtf16 . unLE++-- | For strict ByteStrings; goes via a strict Text. Equivalent to+-- the @LittleEndian (Utf16 ByteString)@ instance.+instance BuildFrom T.Builder (Utf16 (LittleEndian SB.ByteString)) where+ fromValue = T.fromText . ST.decodeUtf16LE . unLE . unUtf16++-- | For strict ByteStrings; goes via a strict Text. Equivalent to+-- the @Utf32 (BigEndian ByteString)@ instance.+instance BuildFrom T.Builder (BigEndian (Utf32 SB.ByteString)) where+ fromValue = T.fromText . ST.decodeUtf32BE . unUtf32 . unBE++-- | For strict ByteStrings; goes via a strict Text. Equivalent to+-- the @BigEndian (Utf32 ByteString)@ instance.+instance BuildFrom T.Builder (Utf32 (BigEndian SB.ByteString)) where+ fromValue = T.fromText . ST.decodeUtf32BE . unBE . unUtf32++-- | For strict ByteStrings; goes via a strict Text. Equivalent to+-- the @Utf32 (LittleEndian ByteString)@ instance.+instance BuildFrom T.Builder (LittleEndian (Utf32 SB.ByteString)) where+ fromValue = T.fromText . ST.decodeUtf32LE . unUtf32 . unLE++-- | For strict ByteStrings; goes via a strict Text. Equivalent to+-- the @LittleEndian (Utf32 ByteString)@ instance.+instance BuildFrom T.Builder (Utf32 (LittleEndian SB.ByteString)) where+ fromValue = T.fromText . ST.decodeUtf32LE . unLE . unUtf32++-- | For lazy ByteStrings; goes via a lazy Text.+instance BuildFrom T.Builder (Char8 LB.ByteString) where+ fromValue = T.fromLazyText . LT.decodeLatin1 . unChar8++-- | For lazy ByteStrings; goes via a lazy Text.+instance BuildFrom T.Builder (Utf8 LB.ByteString) where+ fromValue = T.fromLazyText . LT.decodeUtf8 . unUtf8++-- | For lazy ByteStrings; goes via a lazy Text. Equivalent to+-- the @Utf16 (BigEndian ByteString)@ instance.+instance BuildFrom T.Builder (BigEndian (Utf16 LB.ByteString)) where+ fromValue = T.fromLazyText . LT.decodeUtf16BE . unUtf16 . unBE++-- | For lazy ByteStrings; goes via a lazy Text. Equivalent to+-- the @BigEndian (Utf16 ByteString)@ instance.+instance BuildFrom T.Builder (Utf16 (BigEndian LB.ByteString)) where+ fromValue = T.fromLazyText . LT.decodeUtf16BE . unBE . unUtf16++-- | For lazy ByteStrings; goes via a lazy Text. Equivalent to+-- the @Utf16 (LittleEndian ByteString)@ instance.+instance BuildFrom T.Builder (LittleEndian (Utf16 LB.ByteString)) where+ fromValue = T.fromLazyText . LT.decodeUtf16LE . unUtf16 . unLE++-- | For lazy ByteStrings; goes via a lazy Text. Equivalent to+-- the @LittleEndian (Utf16 ByteString)@ instance.+instance BuildFrom T.Builder (Utf16 (LittleEndian LB.ByteString)) where+ fromValue = T.fromLazyText . LT.decodeUtf16LE . unLE . unUtf16++-- | For lazy ByteStrings; goes via a lazy Text. Equivalent to+-- the @Utf32 (BigEndian ByteString)@ instance.+instance BuildFrom T.Builder (BigEndian (Utf32 LB.ByteString)) where+ fromValue = T.fromLazyText . LT.decodeUtf32BE . unUtf32 . unBE++-- | For lazy ByteStrings; goes via a lazy Text. Equivalent to+-- the @BigEndian (Utf32 ByteString)@ instance.+instance BuildFrom T.Builder (Utf32 (BigEndian LB.ByteString)) where+ fromValue = T.fromLazyText . LT.decodeUtf32BE . unBE . unUtf32++-- | For lazy ByteStrings; goes via a lazy Text. Equivalent to+-- the @Utf32 (LittleEndian ByteString)@ instance.+instance BuildFrom T.Builder (LittleEndian (Utf32 LB.ByteString)) where+ fromValue = T.fromLazyText . LT.decodeUtf32LE . unUtf32 . unLE++-- | For lazy ByteStrings; goes via a lazy Text. Equivalent to+-- the @LittleEndian (Utf32 ByteString)@ instance.+instance BuildFrom T.Builder (Utf32 (LittleEndian LB.ByteString)) where+ fromValue = T.fromLazyText . LT.decodeUtf32LE . unLE . unUtf32++-- -----------------------------------------------------------------------------+-- Sequences++instance Buildable (S.Seq a) where+ type Unit (S.Seq a) = a+ type Builder (S.Seq a) = S.Seq a++ build = id++instance BuildFrom (S.Seq a) (S.Seq a) where+ fromValue = id++instance BuildFrom (S.Seq a) a where+ fromValue = S.singleton++ prepend = (S.<|)++ append = (S.|>)++instance BuildFrom (S.Seq a) [a] where+ fromValue = S.fromList