Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
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
>>>
helloB64
MkEnc Proxy () "SGVsbG8gV29ybGQ="
>>>
displ helloB64
"MkEnc '[enc-B64] () (ByteString SGVsbG8gV29ybGQ=)"
>>>
encodeAll . toEncoding () $ "Hello World" :: Enc '["enc-B64"] () B.ByteString
MkEnc 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.ByteString
MkEnc 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.ByteString
MkEnc Proxy () "SGVsbG8gV29ybGQ="
>>>
helloB64B64PartDecode == helloB64
True
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.Text
MkEnc Proxy () "HELLO WORLD"
helloTitleRev :: Enc '["do-reverse", "do-Title"] () Text Source #
Sample compound transformation
>>>
encodeAll . toEncoding () $ "HeLLo world" :: Enc '["do-reverse", "do-Title"] () T.Text
MkEnc Proxy () "dlroW olleH"
Configuration
Example 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.Text
MkEnc Proxy (Config {sizeLimit = SizeLimit {unSizeLimit = 8}}) "dlroW olleH"
>>>
encodeAll . toEncoding exampleConf $ "HeLlo world" :: Enc '["do-size-limit", "do-reverse", "do-Title"] Config T.Text
MkEnc 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.Text
MkEnc 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"]) $ helloLimitB64
MkEnc 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"]) <$> helloAsciiB64
Right (MkEnc Proxy () "Hello World")