| Safe Haskell | Safe |
|---|---|
| Language | Haskell2010 |
Examples.TypedEncoding.Overview
Description
type-encoding overview examples.
This library is concerned with 3 main operations done on strings: encoding, decoding, and recovery. Examples in this module cover all of these base cases.
This module uses encoding instances found in
Synopsis
- helloB64 :: Enc '["enc-B64"] () ByteString
- helloB64Decoded :: ByteString
- helloB64Recovered :: Either RecreateEx (Enc '["enc-B64"] () ByteString)
- helloB64B64 :: Enc '["enc-B64", "enc-B64"] () ByteString
- helloB64B64PartDecode :: Enc '["enc-B64"] () ByteString
- helloB64B64Decoded :: ByteString
- helloB64B64RecoveredErr :: Either RecreateEx (Enc '["enc-B64", "enc-B64"] () ByteString)
- helloUPP :: Enc '["do-UPPER"] () Text
- helloTitleRev :: Enc '["do-reverse", "do-Title"] () Text
- data Config = Config {}
- exampleConf :: Config
- helloTitle :: Enc '["do-Title"] Config Text
- helloRevLimit :: Enc '["do-size-limit", "do-reverse", "do-Title"] Config Text
- helloLimitB64 :: Enc '["enc-B64", "do-size-limit"] Config ByteString
- helloRevLimitParDec :: Enc '["do-size-limit"] Config ByteString
- helloAscii :: Either EncodeEx (Enc '["r-ASCII"] () ByteString)
- helloAsciiB64 :: Either EncodeEx (Enc '["enc-B64", "r-ASCII"] () ByteString)
- helloAsciiB64PartDec :: Either EncodeEx (Enc '["r-ASCII"] () ByteString)
Documentation
>>>:set -XOverloadedStrings -XMultiParamTypeClasses -XDataKinds
This module contains some ghci friendly values to play with.
Each value is documented in a doctest style by including an equivalent ghci ready expression. These documents generate a test suite for this library as well.
Basics
helloB64 :: Enc '["enc-B64"] () ByteString Source #
"Hello World" encoded as Base64
>>>helloB64MkEnc Proxy () "SGVsbG8gV29ybGQ="
>>>displ helloB64"MkEnc '[enc-B64] () (ByteString SGVsbG8gV29ybGQ=)"
>>>encodeAll . toEncoding () $ "Hello World" :: Enc '["enc-B64"] () B.ByteStringMkEnc Proxy () "SGVsbG8gV29ybGQ="
helloB64Decoded :: ByteString Source #
Previous text decoded from Base64
>>>fromEncoding . decodeAll $ helloB64"Hello World"
helloB64Recovered :: Either RecreateEx (Enc '["enc-B64"] () ByteString) Source #
recreateFAll allows for recovering data at program boundaries (for example, when parsing JSON input).
It makes sure that the content satisfies specified encodings.
>>>recreateFAll . toEncoding () $ "SGVsbG8gV29ybGQ=" :: Either RecreateEx (Enc '["enc-B64"] () B.ByteString)Right (MkEnc Proxy () "SGVsbG8gV29ybGQ=")
>>>recreateFAll . toEncoding () $ "SGVsbG8gV29ybGQ" :: Either RecreateEx (Enc '["enc-B64"] () B.ByteString)Left (RecreateEx "enc-B64" ("invalid padding"))
helloB64B64 :: Enc '["enc-B64", "enc-B64"] () ByteString Source #
"Hello World" double-Base64 encoded. Notice the same code used as in single encoding, the game is played at type level.
>>>encodeAll . toEncoding () $ "Hello World" :: Enc '["enc-B64","enc-B64"] () B.ByteStringMkEnc Proxy () "U0dWc2JHOGdWMjl5YkdRPQ=="
>>>displ helloB64B64"MkEnc '[enc-B64,enc-B64] () (ByteString U0dWc2JHOGdWMjl5YkdRPQ==)"
helloB64B64PartDecode :: Enc '["enc-B64"] () ByteString Source #
Double Base64 encoded "Hello World" with one layer of encoding removed
>>>decodePart (Proxy :: Proxy '["enc-B64"]) $ helloB64B64 :: Enc '["enc-B64"] () B.ByteStringMkEnc Proxy () "SGVsbG8gV29ybGQ="
>>>helloB64B64PartDecode == helloB64True
helloB64B64Decoded :: ByteString Source #
helloB64B64 all the way to ByteString
Notice a similar polymorphism in decoding.
>>>fromEncoding . decodeAll $ helloB64B64 :: B.ByteString"Hello World"
We can also decode all the parts:
>>>fromEncoding . decodePart (Proxy :: Proxy '["enc-B64","enc-B64"]) $ helloB64B64"Hello World"
helloB64B64RecoveredErr :: Either RecreateEx (Enc '["enc-B64", "enc-B64"] () ByteString) Source #
what happens when we try to recover encoded once text to Enc '["enc-B64", "enc-B64"].
Again, notice the same expression is used as in previous recovery.
>>>recreateFAll . toEncoding () $ "SGVsbG8gV29ybGQ=" :: Either RecreateEx (Enc '["enc-B64", "enc-B64"] () B.ByteString)Left (RecreateEx "enc-B64" ("invalid padding"))
"do-" Encodings
helloUPP :: Enc '["do-UPPER"] () Text Source #
"do-UPPER" (from Sample module) encoding applied to "Hello World"
Notice a namespace thing going on, "enc-" is encoding, "do-" is some transformation. These are typically not reversible, some could be recoverable.
The same code is used as in "enc-" examples to encode (now transform).
>>>encodeAll . toEncoding () $ "Hello World" :: Enc '["do-UPPER"] () T.TextMkEnc Proxy () "HELLO WORLD"
helloTitleRev :: Enc '["do-reverse", "do-Title"] () Text Source #
Sample compound transformation
>>>encodeAll . toEncoding () $ "HeLLo world" :: Enc '["do-reverse", "do-Title"] () T.TextMkEnc Proxy () "dlroW olleH"
Configuration
exampleConf :: Config Source #
helloTitle :: Enc '["do-Title"] Config Text Source #
helloTitle is needed in following examples
helloRevLimit :: Enc '["do-size-limit", "do-reverse", "do-Title"] Config Text Source #
Configuration can be used to impact the encoding process.
So far we had used () as configuration of all encodings.
But since both "do-reverse", "do-Title" are polymorphic in
configuration we can also do this:
>>>encodeAll . toEncoding exampleConf $ "HeLLo world" :: Enc '["do-reverse", "do-Title"] Config T.TextMkEnc Proxy (Config {sizeLimit = SizeLimit {unSizeLimit = 8}}) "dlroW olleH"
>>>encodeAll . toEncoding exampleConf $ "HeLlo world" :: Enc '["do-size-limit", "do-reverse", "do-Title"] Config T.TextMkEnc Proxy (Config {sizeLimit = SizeLimit {unSizeLimit = 8}}) "dlroW ol"
Instead, encode previously defined helloTitle by reversing it and adding size limit
>>>encodePart (Proxy :: Proxy '["do-size-limit", "do-reverse"]) helloTitle :: Enc '["do-size-limit", "do-reverse", "do-Title"] Config T.TextMkEnc Proxy (Config {sizeLimit = SizeLimit {unSizeLimit = 8}}) "dlroW ol"
helloLimitB64 :: Enc '["enc-B64", "do-size-limit"] Config ByteString Source #
helloRevLimitParDec :: Enc '["do-size-limit"] Config ByteString Source #
... and we unwrap the B64 part only
>>>decodePart (Proxy :: Proxy '["enc-B64"]) $ helloLimitB64MkEnc Proxy (Config {sizeLimit = SizeLimit {unSizeLimit = 8}}) "HeLlo wo"
"r-" encodings section
helloAscii :: Either EncodeEx (Enc '["r-ASCII"] () ByteString) Source #
ASCII char set
ByteStrings are sequences of Bytes (Word8). The type
is very permissive, it may contain binary data such as jpeg picture.
"r-ASCII" encoding acts as partial identity function
it does not change any bytes in bytestring but it fails if a byte
is outside of ASCII range (in Either monad).
Note naming thing: "r-" is partial identity ("r-" is from restriction).
>>>encodeFAll . toEncoding () $ "HeLlo world" :: Either EncodeEx (Enc '["r-ASCII"] () B.ByteString)Right (MkEnc Proxy () "HeLlo world")
helloAsciiB64 :: Either EncodeEx (Enc '["enc-B64", "r-ASCII"] () ByteString) Source #
Arguably the type we used for helloB64 was too permissive. a better version is here:
>>>encodeFAll . toEncoding () $ "Hello World" :: Either EncodeEx (Enc '["enc-B64", "r-ASCII"] () B.ByteString)Right (MkEnc Proxy () "SGVsbG8gV29ybGQ=")
helloAsciiB64PartDec :: Either EncodeEx (Enc '["r-ASCII"] () ByteString) Source #
>>>decodePart (Proxy :: Proxy '["enc-B64"]) <$> helloAsciiB64Right (MkEnc Proxy () "Hello World")