-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Lists, Texts, ByteStrings, and Vectors with type-encoded length -- -- Sext (static text) provides type-level safety for basic -- operations on string-like types (finite lists of elements). Use it -- when you need static guarantee on lengths of strings produced in your -- code. @package sext @version 0.1.2 -- | Use this only if you need to make some type Sextable. module Data.Sext.Class -- | Class of types which can be assigned a type-level length. class Sextable a where data Sext (i :: Nat) a type Elem a where { data family Sext (i :: Nat) a; type family Elem a; } -- | Simply wrap a value in a Sext as is, assuming any length. -- -- For example, an expression like -- --
-- unsafeCreate "somestring" :: Sext 50 String ---- -- will typecheck, although the stored length information will not match -- actual string size. This may result in wrong behaviour of all -- functions defined for Sext. -- -- Use it only when you know what you're doing. -- -- When implementing new Sextable instances, code this to simply apply -- the constructor of Sext. unsafeCreate :: Sextable a => a -> Sext i a -- | Forget type-level length, obtaining the underlying value. unwrap :: Sextable a => Sext i a -> a length :: Sextable a => a -> Int append :: Sextable a => a -> a -> a replicate :: Sextable a => Int -> Elem a -> a map :: Sextable a => (Elem a -> Elem a) -> a -> a take :: Sextable a => Int -> a -> a drop :: Sextable a => Int -> a -> a instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Sext.Class.Sext i [a]) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Sext.Class.Sext i [a]) instance GHC.Classes.Ord (Data.Sext.Class.Sext i Data.Text.Internal.Text) instance GHC.Classes.Eq (Data.Sext.Class.Sext i Data.Text.Internal.Text) instance GHC.Classes.Ord (Data.Sext.Class.Sext i Data.ByteString.Internal.ByteString) instance GHC.Classes.Eq (Data.Sext.Class.Sext i Data.ByteString.Internal.ByteString) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Sext.Class.Sext i (Data.Vector.Vector a)) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Sext.Class.Sext i (Data.Vector.Vector a)) instance (GHC.Show.Show a, Data.Sext.Class.Sextable a) => GHC.Show.Show (Data.Sext.Class.Sext i a) instance Data.Sext.Class.Sextable [a] instance Data.Sext.Class.Sextable Data.Text.Internal.Text instance Data.Sext.Class.Sextable Data.ByteString.Internal.ByteString instance Data.Sext.Class.Sextable (Data.Vector.Vector a) -- | Template Haskell helpers for Sext. module Data.Sext.TH -- | Type-safe Sext constructor macro for string literals. -- -- Example: -- --
-- $(sext "Foobar") ---- -- compiles to -- --
-- unsafeCreate "Foobar" :: forall a. (IsString a, Sextable a) => Sext 6 a ---- -- where 6 is the string length obtained at compile time. sext :: LitS -> Q Exp instance Data.String.IsString Data.Sext.TH.LitS -- | Sext (static text) provides type-level safety for basic -- operations on string-like types (finite lists of elements). Use it -- when you need static guarantee on lengths of strings produced in your -- code. -- -- An example application would be a network exchange protocol built of -- packets with fixed-width fields: -- --
-- import Data.Sext -- -- mkPacket :: String -> Sext 32 String -- mkPacket inp = -- -- 5-character version signature -- $(sext "PKT10") `append` -- -- 25-character payload -- payload `append` -- -- 2-character payload checksum -- checksum -- where -- payload = createLeft ' ' inp -- checksum :: Sext 2 String -- checksum = createLeft ' ' $ -- show $ Data.Sext.length payload `mod` 100 -- -- message :: Sext 64 String -- message = mkPacket "Hello" `append` mkPacket "world" ---- -- Sext combinators are defined for members of Sextable class. The -- package includes Sextable instances for several common types. -- -- This module is meant to be imported qualifed, e.g. -- --
-- import qualified Data.Sext as S --module Data.Sext -- | Safely create a Sext, possibly altering the source to match target -- length. If target length is less than that of the source, the source -- gets truncated. If target length is greater, the source is padded -- using the provided basic element. Elements on the left are preferred. -- --
-- >>> createLeft ' ' "foobarbaz" :: Sext 6 String -- "foobar" -- -- >>> createLeft '#' "foobarbaz" :: Sext 12 String -- "foobarbaz###" --createLeft :: forall a i. (Sextable a, KnownNat i) => Elem a -> a -> Sext i a -- | Just like createLeft, except that elements on the right are -- preferred. -- --
-- >>> createRight '@' "foobarbaz" :: Sext 6 String -- "barbaz" -- -- >>> createRight '!' "foobarbaz" :: Sext 12 String -- "!!!foobarbaz" --createRight :: forall a i. (Sextable a, KnownNat i) => Elem a -> a -> Sext i a -- | Type-safe Sext constructor macro for string literals. -- -- Example: -- --
-- $(sext "Foobar") ---- -- compiles to -- --
-- unsafeCreate "Foobar" :: forall a. (IsString a, Sextable a) => Sext 6 a ---- -- where 6 is the string length obtained at compile time. sext :: LitS -> Q Exp -- | Attempt to safely create a Sext if it matches target length. -- --
-- >>> create "foobar" :: Maybe (Sext 6 String) -- Just "foobar" -- -- >>> create "barbaz" :: Maybe (Sext 8 String) -- Nothing ---- -- This is safer than unsafeCreate and unlike with -- createLeft / createRight the source value is left -- unchanged. However, this implies a further run-time check for Nothing -- values. create :: forall a i. (Sextable a, KnownNat i) => a -> Maybe (Sext i a) -- | Construct a new Sext from a basic element. -- --
-- >>> replicate '=' :: Sext 10 String -- "==========" --replicate :: forall a i. (Sextable a, KnownNat i) => Elem a -> Sext i a -- | Append two Sexts together. -- --
-- >>> append $(sext "foo") $(sext "bar") :: Sext 6 String -- "foobar" --append :: forall a m n. (Sextable a) => Sext m a -> Sext n a -> Sext (m + n) a -- | Reduce Sext length, preferring elements on the left. -- --
-- >>> take $(sext "Foobar") :: Sext 3 String -- "Foo" --take :: forall a m n. (Sextable a, KnownNat m, KnownNat n, n <= m) => Sext m a -> Sext n a -- | Reduce Sext length, preferring elements on the right. -- --
-- >>> drop $(sext "Foobar") :: Sext 2 String -- "ar" --drop :: forall a m n. (Sextable a, KnownNat m, KnownNat n, n <= m) => Sext m a -> Sext n a -- | Map a Sext to a Sext of the same length. -- --
-- >>> map toUpper $(sext "Hello") :: Sext 5 String -- "HELLO" --map :: Sextable a => (Elem a -> Elem a) -> Sext m a -> Sext m a -- | Fill a Sext with extra elements up to target length, padding original -- elements to the left. padLeft :: forall a m n. (Sextable a, KnownNat m, KnownNat (n - m), n ~ ((n - m) + m), m <= n) => Elem a -> Sext m a -> Sext n a -- | Like padLeft, but original elements are padded to the right. padRight :: forall a m n. (Sextable a, KnownNat m, KnownNat (n - m), n ~ (m + (n - m)), m <= n) => Elem a -> Sext m a -> Sext n a -- | Obtain value-level length. length :: forall a m. KnownNat m => Sext m a -> Int -- | Class of types which can be assigned a type-level length. class Sextable a where data Sext (i :: Nat) a where { data family Sext (i :: Nat) a; } -- | Simply wrap a value in a Sext as is, assuming any length. -- -- For example, an expression like -- --
-- unsafeCreate "somestring" :: Sext 50 String ---- -- will typecheck, although the stored length information will not match -- actual string size. This may result in wrong behaviour of all -- functions defined for Sext. -- -- Use it only when you know what you're doing. -- -- When implementing new Sextable instances, code this to simply apply -- the constructor of Sext. unsafeCreate :: Sextable a => a -> Sext i a -- | Forget type-level length, obtaining the underlying value. unwrap :: Sextable a => Sext i a -> a