úÎ!±ú‡ÿ“      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl m n o p q r s t u v w x y z { | } ~  €  ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ  Ž!!!‘!’!&SafeXkhtyped-encodingIThis class will be removed in 0.3.x.x in favor of classes definined in 8Data.TypedEncoding.Internal.Class.Util.StringConstraints Reverses “laws: : toString . fromString == id fromString . toString == id _Note: ByteString is not a valid instance, ByteString "r-ASCII", or "r-UTF8" would be needed. #B.unpack $ B.pack "160688" == "176"typed-encoding0prop_toStringFromString (Proxy :: Proxy TL.Text) prop_fromStringToString @TL.Texttyped-encoding/prop_toStringFromString (Proxy :: Proxy T.Text)prop_fromStringToString @T.TextSafe-.=>?@AHUVXk2P”typed-encodingŒUsed to find exceptions that violated "r-" encoding Expected to be used to check encoding of ASCII-7 so Text and ByteString are compatible.•typed-encodingSame as ToStrInj but with additionallaw for types that are also IsString:  fromString . toString == id –typed-encoding Reverses “law for types that are also IsString:  toString . fromString == id _Note: ByteString is not a valid instance, ByteString "r-ASCII", or "r-UTF8" would be needed. %B8.unpack $ B8.pack "160688" == "176"This class is separated from ToStrIso to allow instances from smaller types the can inject into the — type.typed-encoding0prop_toStringFromString (Proxy :: Proxy TL.Text)typed-encoding/prop_toStringFromString (Proxy :: Proxy T.Text)typed-encoding prop_fromStringToString @TL.Text typed-encodingprop_fromStringToString @T.Text typed-encodingLB8.pack is basically a convenient way to get Word8 elements into ByteString.pDuring B8.pack conversion charters are downsized to the 0-255 range (become a Word8). The length is preserved. B8.pack "\160582""F"B.length $ B8.pack "\160582"1PThis instance allows to check elementes of ByteString interpreting them as Char.ZThis may or may not work with UTF8 conversions. Safe if restricting to 7bit code points.sSafe3ttyped-encoding+Represents value level (single) annotation.Safe-.=>?@AHUVXk9 typed-encoding/Polymorphic data payloads used to encode/decodetyped-encoding,TODO should this be imported from somewhere?typed-encodingHuman friendly version of Showtyped-encoding!symbolVals @ '["FIRST", "SECOND"]["FIRST","SECOND"]typed-encoding*displ (Proxy :: Proxy ["FIRST", "SECOND"])"[FIRST,SECOND]"Safe&'-.=>?HUVX>ö"typed-encoding¨constructor is to be treated as Unsafe to Encode and Decode instance implementations particular encoding instances may expose smart constructors for limited data types3typed-encodingElet disptest = unsafeSetPayload () "hello" :: Enc '["TEST"] () T.Textdispl disptest"MkEnc '[TEST] () (Text hello)"!"#$%&'()*+,-./012!"#$%&'()*+,-./012Safe &'1SXkIÁ6typed-encoding*Represents some validated encoded string.  CheckedEnc is untyped version of !.  CheckedEncN contains verified encoded data, encoding is visible at the value level only.=typed-encoding;let encsometest = MkCheckedEnc ["TEST"] () $ T.pack "hello"6proc_toCheckedEncFromCheckedEnc @'["TEST"] encsometestTrue7proc_toCheckedEncFromCheckedEnc @'["TEST1"] encsometestFalse>typed-encodingDlet enctest = unsafeSetPayload () "hello" :: Enc '["TEST"] () T.Text'proc_fromCheckedEncToCheckedEnc enctestTrue?typed-encoding8displ $ unsafeCheckedEnc ["TEST"] () ("hello" :: T.Text)%"MkCheckedEnc [TEST] () (Text hello)" 6789:;<=> 6789:;<=>Safe&'-.=>?HUVXkO"Btyped-encoding@Represents some encoded string where encoding was not validated. Similar to " but unlike  CheckedEnc4 it can contain payloads that have invalid encoding.Gtyped-encoding6displ $ MkUncheckedEnc ["TEST"] () ("hello" :: T.Text)'"MkUncheckedEnc [TEST] () (Text hello)"BCDEFBCDEFSafe&'-.=>?HUVXUìJtyped-encodingµType safety over encodings makes decoding process safe. However failures are still possible due to bugs or unsafe payload modifications. UnexpectedDecodeEx represents such errors.Ltyped-encodingRepresents errors in encodingNtyped-encoding<Represents errors in recovery (recreation of encoded types).Rtyped-encoding/usefull when manually recreating using recovery0!"#$%&'()*+,-./0126789:;<=>BCDEFJKLMNOPQRSTUVWXJKLMNOPQRSTUVWX Safe-.>HXd\\typed-encodingÁallows to fold payload in Enc to create another Enc, assumes homogeneous input encodings. This yields not a type safe code, better implementation code should use fixed size dependently typed Vect n or some HList like foldable.]typed-encoding Similar to \', assumes that destination payload has IsString instance and uses "" as base case. ^typed-encoding Similar to \, works with untyped 6_typed-encoding Similar to ], works with untyped 6`typed-encoding0Splits composite payload into homogenious chunksatyped-encodingUntyped version of `btyped-encoding1sometimes show . read is not identity, eg. Word8:read "256" :: Word804verifyWithRead @Word8 "Word8-decimal" (T.pack "256")9Left "Payload does not satisfy format Word8-decimal: 256"4verifyWithRead @Word8 "Word8-decimal" (T.pack "123") Right "123"\]^_`ab\]^_`ab Safe-.=>?@AHUVXh´ctyped-encodingERecovery errors are expected unless Recovery allows Identity instancehtyped-encoding=Used to safely recover encoded data validating all encodingssktyped-encoding'Usefull for partially manual recreationcdegfhijklmnophiegfjklmncdop Safe-.>HXkk+ttyped-encoding*Maybe signals annotation mismatch, effect f' is not evaluated unless there is matchtutu Safe-.=>?@AHUVXmË~typed-encodingffor some reason ApplyTypes syntax does not want to work if xs is specified with polymorphic [Symbol] vwxyz{|}~ xyvwz{|}~ Safe-.=>?@AHUVXqtyped-encoding„With type safety in place decoding errors should be unexpected. This class can be used to provide extra info if decoding could fail ‚ƒ„…†‡ˆ‰Š‹Œ …†ƒ„‡ˆ‰Š‹‚ŒSafe -.=>?@AHUVXvn”typed-encodingVsubsets are useful for restriction encodings like r-UFT8 but not for other encodings.–typed-encoding Reverse of ˜ decodes encoded string back to a˜typed-encodingGeneralized Java toString% or a type safe version of Haskell's ˜.Encodes a as  Enc '[xs].6cdefghijklmnopvwxyz{|}~‚ƒ„…†‡ˆ‰Š‹Œ’“”•–—˜™š› ’“”•–—˜™š›#Safew¤m!"#$%&'()*+,-./0126789:;<=>BCDEFJKLMNOPQRSTUVWX\]^_`abcdefghijklmnopvwxyz{|}~‚ƒ„…†‡ˆ‰Š‹Œ’“”•–—˜™š›Safe-.=>?@AHUVXkzSafe-.=>?@AHUVXhk”ô typed-encodingempty string is valid utf8¡typed-encodingType-safer version of Data.Text.Encoding.encodeUtf8;displ $ text2ByteStringS $ toEncoding () ("text" :: T.Text)&"MkEnc '[r-UTF8] () (ByteString text)"¢typed-encoding3Type-safer version of Data.Text.Encoding.decodeUtf8olet Right tst = encodeFAll . toEncoding () $ "Hello World" :: Either EncodeEx (Enc '["r-UTF8"] () B.ByteString)displ $ byteString2TextS tst!"MkEnc '[] () (Text Hello World)"£typed-encoding•Identity property "byteString2TextS . text2ByteStringS == id" prop> t -> t == (fromEncoding . txtBsSIdProp (Proxy :: Proxy '[]) . toEncoding () $ t)¤typed-encoding>Identity property "text2ByteStringS . byteString2TextS == id".V\(t :: Enc '["r-UTF8"] () B.ByteString) -> t == (bsTxtIdProp (Proxy :: Proxy '[]) $ t)¨typed-encoding–helper function checks that given ByteString, if is encoded as Left is must be not Utf8 decodable is is encoded as Right is must be Utf8 encodable ®typed-encodingYUTF8 encodings are defined for ByteString only as that would not make much sense for Text\encodeFAll . toEncoding () $ "\xc3\xb1" :: Either EncodeEx (Enc '["r-UTF8"] () B.ByteString)!Right (MkEnc Proxy () "\195\177")\encodeFAll . toEncoding () $ "\xc3\x28" :: Either EncodeEx (Enc '["r-UTF8"] () B.ByteString)rLeft (EncodeEx "r-UTF8" (Cannot decode byte '\xc3': Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream))Following test uses ¨Q helper that checks that bytes are encoded as Right iff they are valid UTF8 bytes¶\(b :: B.ByteString) -> verEncoding b (fmap (fromEncoding . decodeAll . proxiedId (Proxy :: Proxy (Enc '["r-UTF8"] _ _))) . (encodeFAll :: _ -> Either EncodeEx _). toEncoding () $ b)  ¡¢£¤¥¦§¨  ¡¢£¤¥¦§¨Safe .=>?@AUVXk•ÚSafe.=>?@AHUVXk–ˆµ¶·µ¶·Safe &'-.=?HUV˜äÅtyped-encoding_Allows to operate within Enc. These are considered unsafe. keeping the same list of encodings ÅÆÇÈÅÆÇÈSafe&'SX›.Îtyped-encodingCSometimes is easier to pass around a proxy than do TypeApplicationsÏtyped-encoding explicit mapMÍÎÏÐÍÎÏÐSafe &'-.HSUVX›äÑÒÓÔÕÑÒÓÔÕSafe &'1SXk¤sÖtyped-encoding%Existentially quantified quanitified Enc effectively isomorphic to 6Útyped-encodingDlet enctest = unsafeSetPayload () "hello" :: Enc '["TEST"] () T.Text#someToChecked . MkSomeEnc $ enctest MkCheckedEnc ["TEST"] () "hello"Ûtyped-encoding-let tst = unsafeCheckedEnc ["TEST"] () "test"displ $ checkedToSome tst"Some (MkEnc '[TEST] () test)"Ütyped-encodingDlet enctest = unsafeSetPayload () "hello" :: Enc '["TEST"] () T.Textdispl $ MkSomeEnc enctest&"Some (MkEnc '[TEST] () (Text hello))"ÖרÙÚÛÖרÙÚÛ$Safe.@A¤ñW!#$/0689:;<BCDEFJKLMNOPQcdefghijklmnoptuvwxyz{|}~‚ƒ„…†‡ˆ‰Š‹Œ’“”•–—˜™š›ÖרÙÚÛ!6LMNOPJK/0$#89:;<QSafe .=>?@AUVk¸Ýtyped-encodingType-safer version of Byte-string to text conversion that prevent invalid UTF8 bytestrings to be conversted to B64 encoded Text.ßtyped-encodingÜConverts encoded text to ByteString adding "r-UTF8" annotation. The question is why "r-UTF8", not for example, "r-UTF16"? No reason, there maybe a diffrent combinator for that in the future or one that accepts a proxy.átyped-encoding|B64 encoded bytestring can be converted to Text as "enc-B64-nontext" preventing it from being B64-decoded directly to Textótyped-encodingÿEffectful instance for corruption detection. This protocol is used, for example, in emails. It is a well known encoding and hackers will have no problem making undetectable changes, but error handling at this stage could verify that email was corrupted.ötyped-encodingCallow to treat B64 encodings as ASCII forgetting about B64 encodingZlet tstB64 = encodeAll . toEncoding () $ "Hello World" :: Enc '["enc-B64"] () B.ByteString<displ (flattenAs tstB64 :: Enc '["r-ASCII"] () B.ByteString)3"MkEnc '[r-ASCII] () (ByteString SGVsbG8gV29ybGQ=)" ÝÞßàáâãäåæ ÝÞßàáâãäåæSafe-.=>?@AHUVX¼ûütyped-encoding :kind! LTake 3 (ToList "123456")ýtyped-encoding:kind! Take 3 "123456"þtyped-encoding<:kind! LDrop 6 (ToList "bool: "r-ban:ff-ff" | "r-ban:ffff"")typed-encodingE:kind! Concat (LDrop 6 (ToList "bool: "r-ban:ff-ff" | "r-ban:ffff""))÷øùúûüýþÿÿþýüûúùø÷Safe .=>?HUVXÁåtyped-encoding:kind! IsR "r-UPPER"... ... 'True:kind! IsR "do-UPPER"...= (TypeError ...  typed-encoding#Universal decode for all "r-" types typed-encodingUManual recreate step combinator converting typical encode function to a recreate step      Safe.=>?@AHUVXkÏb typed-encoding“encFBan . toEncoding () $ "c59f9fb7-4621-44d9-9020-ce37bf6e2bd1" :: Either EncodeEx (Enc '["r-ban:ffffffff-ffff-ffff-ffff-ffffffffffff"] () T.Text)=Right (MkEnc Proxy () "c59f9fb7-4621-44d9-9020-ce37bf6e2bd1")orecWithEncR encFBan . toEncoding () $ "211-22-9934" :: Either RecreateEx (Enc '["r-ban:999-99-9999"] () T.Text)$Right (MkEnc Proxy () "211-22-9934")typed-encodingEverifyBoundedAlphaNum (Proxy :: Proxy "r-ban:ff-ff") (T.pack "12-3e") Right "12-3e"EverifyBoundedAlphaNum (Proxy :: Proxy "r-ban:ff-ff") (T.pack "1g-3e")Left "'g' not boulded by 'f'"EverifyBoundedAlphaNum (Proxy :: Proxy "r-ban:ff-ff") (T.pack "13g3e")Left "'g' not matching '-'"FverifyBoundedAlphaNum (Proxy :: Proxy "r-ban:ff-ff") (T.pack "13-234")GLeft "Input list has wrong size expecting 5 but length \"13-234\" == 6"    Safe.=>?HUVXkñ: typed-encoding):kind! RightTerm "boolSomeOp:(agag)(222)"...= "222" :kind! RightTerm "r-Int-decimal"...= ""typed-encoding(:kind! LeftTerm "boolSomeOp:(agag)(222)"...= "agag":kind! LeftTerm "r-Int-decimal"...= ""typed-encodingreturns "" for unary operatortyped-encoding%:kind! NestedR "boolOr:(r-abc)(r-cd)"...= 'True>:kind! NestedR "boolOr:(boolAnd:(r-ab)(r-ac))(boolNot:(r-cd))"...= 'True[:kind! NestedR "boolOr:(boolAnd:(r-ab)(ac))(boolNot:(r-cd))" ... ... (TypeError ...) ... typed-encodingThis works fast with !kind@ but is much slower in declaration :kind! BoolOp "boolOr:()()"!typed-encoding3:kind! BoolOpIs "boolAnd:(someenc)(otherenc)" "and"...= 'True"typed-encodingSee examples in %#typed-encodingSee examples in %$typed-encoding%typed-encoding:{dlet tst1, tst2, tst3 :: Either EncodeEx (Enc '["boolOr:(r-Word8-decimal)(r-Int-decimal)"] () T.Text)2 tst1 = encBoolOrLeft' . toEncoding () $ "212" 7 tst2 = encBoolOrRight' . toEncoding () $ "1000000" 5 tst3 = encBoolOrLeft' . toEncoding () $ "1000000":}tst1Right (MkEnc Proxy () "212")tst2 Right (MkEnc Proxy () "1000000")tst3\Left (EncodeEx "r-Word8-decimal" ("Payload does not satisfy format Word8-decimal: 1000000"))'typed-encoding"boolOr:(enc1)(enc2)"O contains strings that encode the same way under both encodings. for example "boolOr:(r-UPPER)(r-lower)" valid elements would include "123-34" but not "abc":{_let tst1, tst2 :: Either EncodeEx (Enc '["boolAnd:(r-Word8-decimal)(r-Int-decimal)"] () T.Text). tst1 = encBoolAnd' . toEncoding () $ "234"1 tst2 = encBoolAnd' . toEncoding () $ "100000":}tst1Right (MkEnc Proxy () "234")tst2[Left (EncodeEx "r-Word8-decimal" ("Payload does not satisfy format Word8-decimal: 100000")))typed-encoding:{Plet tst1, tst2 :: Either EncodeEx (Enc '["boolNot:(r-Word8-decimal)"] () T.Text). tst1 = encBoolNot' . toEncoding () $ "334". tst2 = encBoolNot' . toEncoding () $ "127":}tst1Right (MkEnc Proxy () "334")tst2RLeft (EncodeEx "boolNot:(r-Word8-decimal)" ("Encoding r-Word8-decimal succeeded"))*typed-encoding-Decodes boolean expression if all leaves are "r-" !"#$%&'()*+"#$%&'()*+! %Safe &'-.=?HUVò¨ÅÆÇÈSafe .=>?@AUVk÷pAtyped-encodingDallow to treat ASCII encodings as UTF8 forgetting about B64 encodingolet Right tstAscii = encodeFAll . toEncoding () $ "Hello World" :: Either EncodeEx (Enc '["r-ASCII"] () T.Text)"displ (inject @ "r-UTF8" tstAscii)'"MkEnc '[r-UTF8] () (Text Hello World)",-./0123./01,-23Safe .=>?@AUVk*b Etyped-encodingExample value to play with`encodeFAll . toEncoding () $ "HeLlo world" :: Either EncodeEx (Enc '["r-ASCII"] () B.ByteString)$Right (MkEnc Proxy () "HeLlo world")Ftyped-encodingabove with either removedGtyped-encoding3When converted to Text the annotation is preserved.DCurrently separate function is defined for each allowed conversion. ,displ $ EnASCII.byteString2TextS helloAsciiB("MkEnc '[r-ASCII] () (Text HeLlo world)"Htyped-encoding/To get UTF8 annotation, instead of doing this: _encodeFAll . toEncoding () $ "HeLlo world" :: Either EncodeEx (Enc '["r-UTF8"] () B.ByteString)$Right (MkEnc Proxy () "HeLlo world")/We should be able to convert the ASCII version.This is done using ” typeclass.inject1 method accepts proxy to specify superset to use.%displ $ inject @ "r-UTF8" helloAsciiB-"MkEnc '[r-UTF8] () (ByteString HeLlo world)"Ityped-encoding$We put Base64 on the UFT8 ByteString<displ $ encodePart_ (Proxy :: Proxy '["enc-B64"]) helloUtf8B:"MkEnc '[enc-B64,r-UTF8] () (ByteString SGVMbG8gd29ybGQ=)"Jtyped-encoding\.. and copy it over to Text. but UTF8 would be redundant in Text so the "r-UTF8" is dropped':t EnB64.byteString2TextS helloUtf8B64BBEnB64.byteString2TextS helloUtf8B64B :: Enc '["enc-B64"] () T.Text…Conversely moving back to ByteString recovers the annotation. (there could be a choice of a UTF annotation to recover in the future)':t EnB64.text2ByteStringS helloUtf8B64T$EnB64.text2ByteStringS helloUtf8B64T1... :: Enc '["enc-B64", "r-UTF8"] () B.ByteStringKtyped-encodingK7 a binary, one that does not even represent valid UTF8.JencodeAll . toEncoding () $ "\195\177" :: Enc '["enc-B64"] () B.ByteStringMkEnc Proxy () "w7E="áI is a fuction that allows to convert Base 64 ByteString that is not UTF8.#:t EnB64.byteString2TextS' notTextB EnB64.byteString2TextS' notTextB)... :: Enc '["enc-B64-nontext"] () T.TextOThe result is annotated as "enc-B64-nontext" which prevents decoding it within ™< type. We can only move it back to ByteString as "enc-B64".Ltyped-encodingOrecreateAll . toEncoding () $ "abc==CB" :: Enc '["enc-B64-len"] () B.ByteStringMkEnc Proxy () "abc==CB"«The rest of Haskell does lenient decoding, type safety allows this library to use it for recovery. lenient algorithms are not partial and automatically fix invalid input:`recreateFAll . toEncoding () $ "abc==CB" :: Either RecreateEx (Enc '["enc-B64"] () B.ByteString)/Left (RecreateEx "enc-B64" ("invalid padding"))QThis library allows to recover to "enc-B64-len" which is different than "enc-B64"å- allows to convert "enc-B64-len" to "enc-B64"-displ $ EnB64.acceptLenientS lenientSomething'"MkEnc '[enc-B64] () (ByteString abc=)"!This is now properly encoded data]recreateFAll . toEncoding () $ "abc=" :: Either RecreateEx (Enc '["enc-B64"] () B.ByteString)Right (MkEnc Proxy () "abc=")&Except the content could be surprising1decodeAll $ EnB64.acceptLenientS lenientSomethingMkEnc Proxy () "i\183"Mtyped-encoding’Base 64 encodes binary data as ASCII text. thus, we should be able to treat "enc-B64" as "r-ASCII" losing some information. this is done using ’ type class&:t flattenAs @ "r-ASCII" helloUtf8B64B#flattenAs @ "r-ASCII" helloUtf8B64B'... :: Enc '["r-ASCII"] () B.ByteString EFGHIJKLM EFGHIJKLMSafe .=>?@AUVXkDÑNtyped-encoding6encoding function, typically should be module private Otyped-encoding,dual purpose decoding and recovery function.(This typically should be module private.decodeSign "3:abc" Right "abc"decodeSign "4:abc"Left "Corrupted Signature"Ptyped-encodingEncoded hello world example. helloSignedMkEnc Proxy () "11:Hello World"&fromEncoding . decodeAll $ helloSigned "Hello World"Qtyped-encodingproperty checks that ™= values are exected to decode without error after encoding.\t -> propEncDecRtyped-encodingJHacker example The data was transmitted over a network and got corrupted.0let payload = getPayload $ helloSigned :: T.Text%let newpay = payload <> " corruption"WrecreateFAll . toEncoding () $ newpay :: Either RecreateEx (Enc '["my-sign"] () T.Text)3Left (RecreateEx "my-sign" ("Corrupted Signature"))XrecreateFAll . toEncoding () $ payload :: Either RecreateEx (Enc '["my-sign"] () T.Text)'Right (MkEnc Proxy () "11:Hello World")Styped-encodingRecreation allows effectful f? to check for tampering with data. Implementation simply uses '% combinator on the recovery function.Ttyped-encodingDecoding allows effectful f9 to allow for troubleshooting and unsafe payload changes.Implementation simply uses & combinator on the # composed with decoding function.  has Identity instance allowing for decoding that assumes errors are not possible. For debugging purposes or when unsafe changes to "my-sign" Error UnexpectedDecodeEx instance can be used.Utyped-encodingdBecause encoding function is pure we can create instance of EncodeF that is polymorphic in effect f. This is done using * combinator.NOPQRNOPQRSafe.@Ak“üVtyped-encodingExample configurationYtyped-encoding"Hello World" encoded as Base64helloB64!MkEnc Proxy () "SGVsbG8gV29ybGQ="displ helloB643"MkEnc '[enc-B64] () (ByteString SGVsbG8gV29ybGQ=)"MencodeAll . toEncoding () $ "Hello World" :: Enc '["enc-B64"] () B.ByteString!MkEnc Proxy () "SGVsbG8gV29ybGQ="Ztyped-encoding!Previous text decoded from Base64#fromEncoding . decodeAll $ helloB64 "Hello World"[typed-encodingg˜ allows for recovering data at program boundaries (for example, when parsing JSON input). It makes sure that the content satisfies specified encodings.irecreateFAll . toEncoding () $ "SGVsbG8gV29ybGQ=" :: Either RecreateEx (Enc '["enc-B64"] () B.ByteString))Right (MkEnc Proxy () "SGVsbG8gV29ybGQ=")hrecreateFAll . toEncoding () $ "SGVsbG8gV29ybGQ" :: Either RecreateEx (Enc '["enc-B64"] () B.ByteString)/Left (RecreateEx "enc-B64" ("invalid padding"));The above example start by placing payload in zero-encoded  Enc '[] () type and then apply gD this is a good way to recreate encoded type if encoding is known. If is it not, B type can be used. (See &' for better example).7This module is concerned only with the first approach. Llet unchecked = toUncheckedEnc ["enc-B64"] () ("SGVsbG8gV29ybGQ=" :: T.Text)+verifyUncheckedEnc' @'["enc-B64"] unchecked0Just (Right (MkEnc Proxy () "SGVsbG8gV29ybGQ="))\typed-encodingx"Hello World" double-Base64 encoded. Notice the same code used as in single encoding, the game is played at type level.WencodeAll . toEncoding () $ "Hello World" :: Enc '["enc-B64","enc-B64"] () B.ByteString)MkEnc Proxy () "U0dWc2JHOGdWMjl5YkdRPQ=="displ helloB64B64C"MkEnc '[enc-B64,enc-B64] () (ByteString U0dWc2JHOGdWMjl5YkdRPQ==)"]typed-encodingFDouble Base64 encoded "Hello World" with one layer of encoding removedJdecodePart @'["enc-B64"] $ helloB64B64 :: Enc '["enc-B64"] () B.ByteString!MkEnc Proxy () "SGVsbG8gV29ybGQ="!helloB64B64PartDecode == helloB64True^typed-encoding\ all the way to š*Notice a similar polymorphism in decoding.6fromEncoding . decodeAll $ helloB64B64 :: B.ByteString "Hello World""We can also decode all the parts: ?fromEncoding . decodePart @'["enc-B64","enc-B64"] $ helloB64B64 "Hello World"_typed-encoding9what happens when we try to recover encoded once text to Enc '["enc-B64", "enc-B64"]. CAgain, notice the same expression is used as in previous recovery. trecreateFAll . toEncoding () $ "SGVsbG8gV29ybGQ=" :: Either RecreateEx (Enc '["enc-B64", "enc-B64"] () B.ByteString)/Left (RecreateEx "enc-B64" ("invalid padding"))`typed-encoding"do-UPPER" (from ()* 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.FThe same code is used as in "enc-" examples to encode (now transform).HencodeAll . toEncoding () $ "Hello World" :: Enc '["do-UPPER"] () T.TextMkEnc Proxy () "HELLO WORLD"atyped-encodingSample compound transformation VencodeAll . toEncoding () $ "HeLLo world" :: Enc '["do-reverse", "do-Title"] () T.TextMkEnc Proxy () "dlroW olleH" ctyped-encodingc is needed in following examplesdtyped-encoding9Configuration 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:cencodeAll . toEncoding exampleConf $ "HeLLo world" :: Enc '["do-reverse", "do-Title"] Config T.TextLMkEnc Proxy (Config {sizeLimit = SizeLimit {unSizeLimit = 8}}) "dlroW olleH"tencodeAll . toEncoding exampleConf $ "HeLlo world" :: Enc '["do-size-limit", "do-reverse", "do-Title"] Config T.TextIMkEnc Proxy (Config {sizeLimit = SizeLimit {unSizeLimit = 8}}) "dlroW ol"#Instead, encode previously defined c& by reversing it and adding size limityencodePart @'["do-size-limit", "do-reverse"] helloTitle :: Enc '["do-size-limit", "do-reverse", "do-Title"] Config T.TextIMkEnc Proxy (Config {sizeLimit = SizeLimit {unSizeLimit = 8}}) "dlroW ol"ftyped-encoding#... and we unwrap the B64 part only(decodePart @'["enc-B64"] $ helloLimitB64IMkEnc Proxy (Config {sizeLimit = SizeLimit {unSizeLimit = 8}}) "HeLlo wo"gtyped-encoding4ASCII char set ByteStrings are sequences of Bytes (*+Q). 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).GNote 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")htyped-encodingUArguably the type we used for helloB64 was too permissive. a better version is here:kencodeFAll . toEncoding () $ "Hello World" :: Either EncodeEx (Enc '["enc-B64", "r-ASCII"] () B.ByteString)*Right (MkEnc Proxy () "SGVsbG8gV29ybGQ=") ityped-encoding*decodePart @'["enc-B64"] <$> helloAsciiB64$Right (MkEnc Proxy () "Hello World")VWXYZ[\]^_`abcdefghiYZ[\]^_`aVWXbcdefghi Safe.456=>?@AXhkåò ntyped-encoding4This section shows a type safe processing of emails.nC is an over-simplified email type, it has parts that can be either )binary and have to be Base 64 encoded or 6are text that have either UTF8 or ASCII character set NThe text parts can be optionally can be Base 64 encoded but do not have to be.mFor simplicity, the layout of simplified headers is assumed the same as encoding annotations in this library.rtyped-encodingSimplified Email header styped-encodingSimplified Part header ttyped-encoding¹In this example all data fields have the same type. This simplifies encoding work as all fields will be encoded the same way. We use IP address since all fields are single byte size.|typed-encodingtstEmail' contains some simple data to play with}typed-encodingThis example encodes fields in n into an untyped version of Enc_ which stores verified encoded data and encoding information is stored at the value level: CheckedEnc () B.ByteString.%Part of email are first converted to BA (that stores encoding information at the value level as well). B. that can easily represent parts of the email let part = parts tstEmail L.!! 2part-(["enc-B64","r-UTF8"],"U29tZSBVVEY4IFRleHQ=")7let unchecked = toUncheckedEnc (fst part) () (snd part) unchecked=MkUncheckedEnc ["enc-B64","r-UTF8"] () "U29tZSBVVEY4IFRleHQ=" We can play › (œ) game (we acually use Maybe) with final option being a N error:7verifyUncheckedEnc' @'["enc-B64","r-ASCII"] $ uncheckedNothing6verifyUncheckedEnc' @'["enc-B64","r-UTF8"] $ unchecked4Just (Right (MkEnc Proxy () "U29tZSBVVEY4IFRleHQ="))€Since the data is heterogeneous (each piece has a different encoding annotation), we need wrap the result in another plain ADT: 6.6 is similar to Bc with the difference that the only (safe) way to get values of this type is from properly encoded ! values. Using 8 would break type safety here. YIt is important to handle all cases during encoding so decoding errors become impossible.vAgain, use of dependently typed variant types that could enumerate all possible encodings would made this code nicer.~typed-encodingNExample decodes parts of email that are base 64 encoded text and nothing else.‰This provides a type safety assurance that we do not decode certain parts of email (like trying to decode base 64 on a plain text part).2decodeB64ForTextOnly <$> recreateEncoding tstEmailÿRight (SimplifiedEmailF {emailHeader = "Some Header", parts = [MkCheckedEnc ["enc-B64"] () "U29tZSBBU0NJSSBUZXh0",MkCheckedEnc ["r-ASCII"] () "Some ASCII Text",MkCheckedEnc ["r-UTF8"] () "Some UTF8 Text",MkCheckedEnc ["r-ASCII"] () "Some ASCII plain text"]}) Combinator &fromCheckedEnc @'["enc-B64", "r-UTF8"]( acts as a selector and picks only the ["enc-B64", "r-UTF8"] values from our  type.  We play the (œK) game on all the selectors we want picking and decoding right pieces only."Imagine this is one of the pieces:^let piece = unsafeCheckedEnc ["enc-B64","r-ASCII"] () ("U29tZSBBU0NJSSBUZXh0" :: B.ByteString) displ pieceE"MkCheckedEnc [enc-B64,r-ASCII] () (ByteString U29tZSBBU0NJSSBUZXh0)"This code will not pick it up:/fromCheckedEnc @ '["enc-B64", "r-UTF8"] $ pieceNothingBut this one will:1fromCheckedEnc @ '["enc-B64", "r-ASCII"] $ piece,Just (MkEnc Proxy () "U29tZSBBU0NJSSBUZXh0")3so we can apply the decoding on the selected piece afmap (toCheckedEnc . decodePart @'["enc-B64"]) . fromCheckedEnc @ '["enc-B64", "r-ASCII"] $ piece4Just (MkCheckedEnc ["r-ASCII"] () "Some ASCII Text")‚typed-encoding*Provides easy to read encoding informationƒtyped-encoding-let enc = toEncString @"r-IPv4" @T.Text tstIpfromEncString @IpV4 enc1IpV4F {oct1 = 128, oct2 = 1, oct3 = 1, oct4 = 10}To get z/ out of the string we need to reverse previous reduce'. This is currently done using helper ` combinator. FEnT.splitPayload @ '["r-Word8-decimal"] (T.splitOn $ T.pack ".") $ encP[MkEnc Proxy () "128",MkEnc Proxy () "1",MkEnc Proxy () "1",MkEnc Proxy () "10"]cThe conversion of a list to IpV4F needs handle errors but these errors are considered unexpected.\Note, again, the error condition exposed by this implementation could have been avoided if ` returned fixed size Vect 4.„typed-encodingIn this example  toEncString converts z to Enc '["r-IPv4"] Text.#This is done with help of existing "r-Word8-decimal" annotation defined in /Data.TypedEncoding.Instances.Restriction.Common#toEncString @"r-IPv4" @T.Text tstIpMkEnc Proxy () "128.1.1.10"JImplementation is a classic map reduce where reduce is done with help of ]1let fn a b = if b == "" then a else a <> "." <> bDlet reduce = EnT.foldEncStr @'["r-IPv4"] @'["r-Word8-decimal"] () fn)displ . reduce . fmap toEncString $ tstIp "MkEnc '[r-IPv4] () 128.1.1.10" \Note lack of type safety here, the same code would work just fine if we added 5th field to t constructor. (Using something like a dependently typed ,Vect 4 (Enc '["r-Word8-decimal"] () T.Text) %would have improved this situation. HList: could be used for record types with heterogeneous fields. Currently, 'type-encoding'. library does not have these types in scope. …typed-encoding*Provides easy to read encoding informationlmnoqprstuyxwvz{|}~€ztuyxwv{srnoqpml|}~€!Safe .=>?@AUVøÒŽtyped-encodingStarting exampletyped-encodingwith either removedtyped-encodingg- is the way to recover encoding in a safe way!let payload = getPayload exAsciiT/let newPayload = payload <> " some extra stuff"[recreateFAll . toEncoding () $ newPayload :: Either RecreateEx (Enc '["r-ASCII"] () T.Text)/Right (MkEnc Proxy () "HELLO some extra stuff")Alternatively, B% type can be used in recreation, see &,‘typed-encodingThe issue with g is that it may be expensive.This apprach uses %-B to perform (in general risky) operation on the internal payload. exAsciiTERight (MkEnc Proxy () "HELLO")7exAsciiTE >>= pure . Unsafe.withUnsafe (fmap T.toLower)Right (MkEnc Proxy () "hello")Example uses of žH within encoded data this operation is safe for ASCII restriction but Enc '["r-ASCII"] () T.TextV does not expose it We use Functor instance of Unsafe wrapper type to accomplish this’typed-encoding-Similar example uses applicative instance of Ålet Right hELLO = exAsciiTElet Right hello = toLowerAsciiOdispl $ Unsafe.runUnsafe ((<>) <$> Unsafe.Unsafe hELLO <*> Unsafe.Unsafe hello)'"MkEnc '[r-ASCII] () (Text HELLOhello)"Ž‘’Ž‘’&Safeù0=EFGHIJKLMNOPQRVWXYZ[\]^_`abcdefghilmnopqrstuvwxyz{|}~€Ž‘’.SafeúbŸ ¡¢£¤¥¦§/0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcd"efghijklmnopqrstuvwxxyyzz{|}~€‚ƒ„…† ‡ ˆ ‰ Š ‹ Œ Ž  ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼½¾¿ÀÁÂ'ÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÓÔÕÖרÙÙÚÛÜÝÞßàáÔâãäåæ--çèéêëìíîïðñòóôõö÷øùúûüÌÐËÏýþÿÔÓÛ×ÖÜÝÞ      !"#$%&'()*+,-./0123456789:;<=>?@@ÌÐËÏABÓÔÕÖרCDEFGHIJKLMNOPQRSTUVWÔÓÛXXYZ[\]^_`abcdefghijkl m n o o p q r s t t u v w x y z { | } ~  €  ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ!!Ž!!!‘’“”•–—’˜™’š›œžŸ ¡’˜¢’˜£’¤¥œ¦§.¨.©.ª.«.¬.­.®.¯°,typed-encoding-0.2.1.0-SoHkvbF5fMH8LY4y44Y5R+Data.TypedEncoding.Internal.Class.IsStringR8Data.TypedEncoding.Internal.Class.Util.StringConstraints(Data.TypedEncoding.Internal.Types.Common&Data.TypedEncoding.Internal.Class.Util%Data.TypedEncoding.Internal.Types.Enc,Data.TypedEncoding.Internal.Types.CheckedEnc.Data.TypedEncoding.Internal.Types.UncheckedEnc!Data.TypedEncoding.Internal.Types1Data.TypedEncoding.Internal.Instances.Combinators*Data.TypedEncoding.Internal.Class.Recreate'Data.TypedEncoding.Internal.Combinators(Data.TypedEncoding.Internal.Class.Encode(Data.TypedEncoding.Internal.Class.Decode!Data.TypedEncoding.Internal.Class/Data.TypedEncoding.Instances.ToEncString.Common-Data.TypedEncoding.Instances.Restriction.UTF8/Data.TypedEncoding.Instances.Restriction.Common&Data.TypedEncoding.Instances.Do.Sample(Data.TypedEncoding.Internal.Types.Unsafe Data.TypedEncoding.Internal.Util0Data.TypedEncoding.Internal.Types.SomeAnnotation)Data.TypedEncoding.Internal.Types.SomeEnc'Data.TypedEncoding.Instances.Enc.Base64)Data.TypedEncoding.Internal.Util.TypeLits1Data.TypedEncoding.Combinators.Restriction.Common;Data.TypedEncoding.Combinators.Restriction.BoundedAlphaNums/Data.TypedEncoding.Combinators.Restriction.Bool.Data.TypedEncoding.Instances.Restriction.ASCII"Examples.TypedEncoding.Conversions&Examples.TypedEncoding.DiySignEncodingExamples.TypedEncoding.Overview"Examples.TypedEncoding.ToEncStringExamples.TypedEncoding.Unsafe CheckedEnc$Data.TypedEncoding.Instances.SupportData.TypedEncodingData.TypedEncoding.UnsafeExamples.TypedEncoding ToEncStringData.TypedEncoding.Instances.DoSample Data.WordWord8OverviewUnsafePaths_typed_encoding IsStringRtoStringprop_fromStringToStringprop_toStringFromString$fIsStringRText$fIsStringRText0$fToStrInj[]Text$fToStrInj[]Text0$fToStrIso[]Text$fToStrIso[]Text0$fChar7FindByteString$fChar7FindByteString0$fChar7FindText$fChar7FindText0EncAnnHasAhasAppendDispldispl SymbolList symbolVals symbolVals_ $fSymbolList:$fSymbolList[] $fDisplProxy$fDisplByteString$fDisplByteString0 $fDisplText $fDisplText0 $fDispl[] $fDispl[]0 $fHasA()cEncMkEnc toEncoding fromEncoding implTranF implDecodeFimplCheckPrevF implTranF' implDecodeF' implTranP implEncodeP implTranP' implEncodeP' implChangeAnn getPayloadunsafeSetPayloadwithUnsafeCoerceunsafeChangePayload $fDisplEnc $fShowEnc$fEqEnc MkCheckedEncunsafeCheckedEncgetCheckedPayloadgetCheckedEncPayload toCheckedEncfromCheckedEncproc_toCheckedEncFromCheckedEncproc_fromCheckedEncToCheckedEnc$fDisplCheckedEnc$fShowCheckedEnc$fEqCheckedEnc UncheckedEncMkUncheckedEnctoUncheckedEncgetUncheckedEncAnn verifyAnn$fDisplUncheckedEnc$fShowUncheckedEnc$fEqUncheckedEncUnexpectedDecodeExEncodeEx RecreateExRecreateExUnkSteprecreateErrUnknown encToRecrEx mergeEncodeEx emptyEncErr implEncodeF_ implEncodeF implEncodeF_' mergeErrs$fShowRecreateEx$fShowEncodeEx$fShowUnexpectedDecodeExfoldEnc foldEncStrfoldCheckedEncfoldCheckedEncStr splitPayloadsplitSomePayloadverifyWithRead RecreateErr recoveryErr RecreateFAll checkFAll recreateFAll RecreateF checkPrevF recreateAllrecreateFPart_ recreateFPart recreatePart_ recreatePartasRecreateErr_ asRecreateErr$fRecreateFAllf:cstr$fRecreateFAllf[]cstr$fRecreateErrTYPEEitherverifyUncheckedEncverifyUncheckedEnc' EncodeFAll encodeFAllEncodeFencodeF encodeAll encodeFPart_ encodeFPart encodePart_ encodePart$fEncodeFAllf:cstr$fEncodeFAllf[]cstrUnexpectedDecodeErrunexpectedDecodeErr DecodeFAll decodeFAllDecodeFdecodeF decodeAll decodeFPart_ decodeFPart decodePart_ decodePart asUnexpected_ asUnexpected$fDecodeFAllf:cstr$fDecodeFAllf[]cstr$fUnexpectedDecodeErrTYPEEither!$fUnexpectedDecodeErrTYPEIdentity FlattenAs flattenAsSupersetinject FromEncStringfromEncStringF toEncStringF toEncString fromEncString-$fFromEncStringTYPEWord8fstr"r-Word8-decimal".$fToEncString"r-Word8-decimal"strIdentityWord8*$fToEncString"r-Int-decimal"strIdentityInt $fToEncString"r-()"strIdentity() emptyUTF8Btext2ByteStringSbyteString2TextS txtBsSIdProp bsTxtIdProptext2ByteStringLbyteString2TextLprxyUtf8 verEncoding$fDecodeFTYPEfEncEnc$fRecreateFTYPEfEncEnc$fEncodeFTYPEEitherEncEnc$fDecodeFTYPEfEncEnc0$fRecreateFTYPEfEncEnc0$fEncodeFTYPEEitherEncEnc0 SizeLimit unSizeLimit$fEncodeFTYPEfEncEnc$fEncodeFTYPEfEncEnc0$fEncodeFTYPEfEncEnc1$fEncodeFTYPEfEncEnc2$fEncodeFTYPEfEncEnc3$fEncodeFTYPEfEncEnc4$fEncodeFTYPEfEncEnc5$fEncodeFTYPEfEncEnc6$fEncodeFTYPEfEncEnc7$fEncodeFTYPEfEncEnc8 $fEqSizeLimit$fShowSizeLimit runUnsafe withUnsafe $fMonadUnsafe$fApplicativeUnsafe$fFunctorUnsafe $fShowUnsafe explainBool proxiedId extractEitherwithSomeSymbolSomeAnnotationMkSomeAnnotationwithSomeAnnotation someAnnValue proxyConsSomeEnc MkSomeEnc withSomeEnctoSome someToChecked checkedToSome$fDisplSomeEncbyteString2TextS'byteString2TextL'text2ByteStringS'text2ByteStringL'acceptLenientSacceptLenientL$fRecreateFTYPEfEncEnc1$fRecreateFTYPEfEncEnc2$fDecodeFTYPEfEncEnc1$fRecreateFTYPEfEncEnc3$fRecreateFTYPEfEncEnc4$fDecodeFTYPEfEncEnc2$fFlattenAs"r-ASCII""enc-B64"%$fFlattenAs"r-ASCII""enc-B64-nontext"LLenghLengthLTakeUntilHelper LTakeUntil TakeUntilLTakeTakeLDropDropConcatDuplFstRepeatOrAndAcceptEq IsROrEmptyIsRdecFR recWithEncRunsafeRecWithEncRIsBanencFBanverifyBoundedAlphaNum LTakeSndParen LTakeFstParenLParenCntHelper AdjHelperAdjustIncrDecrNoChng LParenCnt LDropLast RightTermLeftTerm SecondTerm FirstTermNestedRIsBool BoolOpHelperBoolOpBoolOpIs encBoolOrLeftencBoolOrLeft'encBoolOrRightencBoolOrRight' encBoolAnd encBoolAnd' encBoolNot encBoolNot'decBoolRrecWithEncBoolR NonAsciiChar prxyAscii encodeImpl$fEncodeFTYPEEitherEncEnc1$fEncodeFTYPEEitherEncEnc2$fDecodeFTYPEfEncEnc3$fSuperset"r-UTF8""r-ASCII"$fEncodeFTYPEEitherEncEnc3$fEqNonAsciiChar$fShowNonAsciiChar eHelloAsciiB helloAsciiB helloAsciiT helloUtf8B helloUtf8B64B helloUtf8B64TnotTextBlenientSomething b64IsAscii encodeSign decodeSign helloSigned propEncDechackerConfig sizeLimithelloB64helloB64DecodedhelloB64Recovered helloB64B64helloB64B64PartDecodehelloB64B64DecodedhelloB64B64RecoveredErrhelloUPP helloTitleRev exampleConf helloTitle helloRevLimit helloLimitB64helloRevLimitParDec helloAscii helloAsciiB64helloAsciiB64PartDec$fHasASizeLimitConfig $fShowConfigSimplifiedEmailEncBSimplifiedEmailSimplifiedEmailF emailHeaderparts EmailHeader PartHeaderIpV4Foct1oct2oct3oct4IpV4tstIptstEmailrecreateEncodingdecodeB64ForTextOnlyrunAlternatives'runAlternatives alternatives $fDisplIpV4F%$fFromEncStringTYPEIpV4FfText"r-IPv4"&$fToEncString"r-IPv4"TextIdentityIpV4F$fDisplSimplifiedEmailF $fShowIpV4F$fFunctorIpV4F$fFoldableIpV4F$fShowSimplifiedEmailF$fEqSimplifiedEmailF$fFunctorSimplifiedEmailF$fFoldableSimplifiedEmailF$fTraversableSimplifiedEmailF exAsciiTEexAsciiTmodifiedAsciiT toLowerAscii appendAsciibase Data.StringIsString Char7FindToStrIsoToStrInjGHC.BaseStringGHC.ShowShow text-1.2.3.1Data.Text.InternalTextbytestring-0.10.8.2Data.ByteString.Internal ByteString Alternative<|>Data.Traversable Traversable Data.TexttoLowerversion getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDirgetDataFileName