type-of-html 1.6.1.2 → 1.6.2.0
raw patch · 8 files changed
+133/−172 lines, 8 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Html.Convert: instance Html.Convert.Convert Html.Convert.Converted
Files
- ChangeLog.md +6/−0
- bench/Alloc.hs +30/−30
- bench/Perf.hs +72/−75
- src/Html.hs +3/−3
- src/Html/Convert.hs +8/−51
- src/Html/Reify.hs +9/−9
- src/Html/Type/Internal.hs +2/−2
- type-of-html.cabal +3/−2
ChangeLog.md view
@@ -1,5 +1,11 @@ # Revision history for type-of-html +## 1.6.2.0 -- 2021-02-06++* simplifications+* performance improvements+* ghc 9 compatibility+ ## 1.6.1.0 -- 2020-11-07 * visual fixes
bench/Alloc.hs view
@@ -24,37 +24,37 @@ main :: IO () main = mainWith $ do - f "()" id () [ 144 , -16 , 16 , 0 , 0 ]- f "Int" id (123456789 :: Int) [ 192 , 0 , 0 , 0 , 0 ]- f "Word" id (123456789 :: Word) [ 192 , 0 , 0 , 0 , 0 ]- f "Char" id 'a' [ 192 , 0 , 0 , 0 , 0 ]- f "Integer" id (123456789 :: Integer) [ 248 , 0 , 0 , 0 , 0 ]- f "Proxy" id (Proxy :: Proxy "a") [ 280 , -16 , 16 , 0 , 0 ]- f "oneElement Proxy" S.oneElement (Proxy :: Proxy "b") [ 280 , -16 , 16 , 0 , 0 ]- f "oneElement ()" S.oneElement () [ 280 , -16 , 16 , 0 , 0 ]- f "oneAttribute ()" (ClassA :=) () [ 280 , -16 , 16 , 0 , 0 ]- f "oneAttribute Proxy" (ClassA :=) (Proxy :: Proxy "c") [ 280 , -16 , 16 , 0 , 0 ]- f "listElement" S.listElement () [ 608 , 0 , 0 , 0 , 0 ]- f "Double" id (123456789 :: Double) [ 360 , 0 , 0 , 0 , -32 ]- f "oneElement" S.oneElement "" [ 368 , 0 , 0 , 0 , 0 ]- f "nestedElement" S.nestedElement "" [ 368 , 0 , 0 , 0 , 0 ]- f "listOfAttributes" (\x -> [ClassA := x, ClassA := x]) () [ 744 , 0 , 0 , 0 , 0 ]- f "Float" id (123456789 :: Float) [ 400 , 0 , 0 , 0 , -72 ]- f "oneAttribute" (ClassA :=) "" [ 480 , 0 , 0 , 0 , 0 ]- f "parallelElement" S.parallelElement "" [ 520 , 0 , 0 , -16 , 0 ]- f "parallelAttribute" (\x -> ClassA := x # IdA := x) "" [ 672 , 0 , 0 , -16 , 0 ]- f "elementWithAttribute" (\x -> Div :@ (ClassA := x) :> x) "" [ 656 , 0 , 0 , 0 , 0 ]- f "listOfListOf" (\x -> Div :> [I :> [Span :> x]]) () [ 1200 , 0 , 64 , 0 , 0 ]- f "helloWorld" M.helloWorld () [ 1232 , -16 , 16 , 0 , 0 ]- f "page" M.page () [ 1416 , -16 , -144 , 0 , 0 ]- f "table" M.table (2,2) [ 2616 , 0 , 64 , -96 , 64 ]- f "AttrShort" M.attrShort () [ 2680 , -16 , 856 , 0 , 0 ]- f "pageA" M.pageA () [ 2504 , -176 , 64 , 0 , 0 ]- f "AttrLong" M.attrLong () [ 2680 , -16 , 856 , 0 , 0 ]- f "Big table" M.table (50,10) [ 120072 , 0 , 1600 , -8096 , 7952 ]- f "hackage upload" EX.hackageUpload () [ 698784 , 488 , -204792 , -1408 , -47120 ]+ f "()" id () [ 144 , -16 , 16 , 0 , 0 , 0 ]+ f "Int" id (123456789 :: Int) [ 192 , 0 , 0 , 0 , 0 , 0 ]+ f "Word" id (123456789 :: Word) [ 192 , 0 , 0 , 0 , 0 , 0 ]+ f "Char" id 'a' [ 256 , 0 , 0 , 0 , 0 , 16 ]+ f "Integer" id (123456789 :: Integer) [ 248 , 0 , 0 , 0 , 0 , 0 ]+ f "Proxy" id (Proxy :: Proxy "a") [ 280 , -16 , 16 , 0 , 0 , 0 ]+ f "oneElement Proxy" S.oneElement (Proxy :: Proxy "b") [ 280 , -16 , 16 , 0 , 0 , 0 ]+ f "oneElement ()" S.oneElement () [ 280 , -16 , 16 , 0 , 0 , 24 ]+ f "oneAttribute ()" (ClassA :=) () [ 280 , -16 , 16 , 0 , 0 , 24 ]+ f "oneAttribute Proxy" (ClassA :=) (Proxy :: Proxy "c") [ 280 , -16 , 16 , 0 , 0 , 0 ]+ f "listElement" S.listElement () [ 608 , 0 , 0 , 0 , 0 , -8 ]+ f "Double" id (123456789 :: Double) [ 360 , 0 , 0 , 0 , -32 , -72 ]+ f "oneElement" S.oneElement "" [ 608 , -32 , -16 , -56 , 0 , 88 ]+ f "nestedElement" S.nestedElement "" [ 608 , -32 , -16 , -56 , 0 , 24 ]+ f "listOfAttributes" (\x -> [ClassA := x, ClassA := x]) () [ 744 , 0 , 0 , 0 , 0 , 8 ]+ f "Float" id (123456789 :: Float) [ 400 , 0 , 0 , 0 , -72 , -72 ]+ f "oneAttribute" (ClassA :=) "" [ 792 , -32 , -16 , -56 , 0 , 16 ]+ f "parallelElement" S.parallelElement "" [ 920 , -64 , -168 , -56 , 0 , 56 ]+ f "parallelAttribute" (\x -> ClassA := x # IdA := x) "" [ 1104 , -64 , -168 , -56 , 0 , 96 ]+ f "elementWithAttribute" (\x -> Div :@ (ClassA := x) :> x) "" [ 1104 , -64 , -168 , -56 , 0 , 32 ]+ f "listOfListOf" (\x -> Div :> [I :> [Span :> x]]) () [ 1200 , 0 , 64 , 0 , 0 , -32 ]+ f "helloWorld" M.helloWorld () [ 480 , -16 , 16 , 0 , 0 , 192 ]+ f "page" M.page () [ 2616 , -176 , -984 , 0 , 0 , 104 ]+ f "table" M.table (2,2) [ 2616 , 0 , 64 , -96 , 64 , -120 ]+ f "AttrShort" M.attrShort () [ 5560 , -400 , -2360 , 0 , 0 , 2688 ]+ f "pageA" M.pageA () [ 5864 , -624 , -2704 , 0 , 0 , 632 ]+ f "AttrLong" M.attrLong () [ 5560 , -400 , -2360 , 0 , 0 , 2736 ]+ f "Big table" M.table (50,10) [ 120072 , 0 , 1600 , -8096 , 7952 , -15288 ]+ f "hackage upload" EX.hackageUpload () [ 852896 , -21952, -558368 , -12248 , 0 , 89336 ] - where versions = [ 802 , 804 , 806 , 808 , 810 ]+ where versions = [ 802 , 804 , 806 , 808 , 810 , 900 ] ghc = fromInteger . sum . take (length $ takeWhile (<= (__GLASGOW_HASKELL__ :: Int)) versions)
bench/Perf.hs view
@@ -3,8 +3,6 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE DataKinds #-} -{-# LANGUAGE CPP #-}- module Main where import Html@@ -15,6 +13,7 @@ import qualified Medium as M import qualified ExampleTypeOfHtml as ET +import Data.Word import Criterion.Main import Data.String import System.Random@@ -23,123 +22,121 @@ import Text.Blaze.Html.Renderer.Utf8 import qualified Data.Text.Lazy as LT import qualified Data.Text as T--#if __GLASGOW_HASKELL__ <= 802-import Data.Semigroup ((<>))-#endif+import Data.ByteString.Lazy (foldl1') main :: IO () main = defaultMain [ small- , medium+ , string , comparison , scaling ] small :: Benchmark small = bgroup "Small"- [ bench "oneElement" $ nf (renderByteString . S.oneElement) ""- , bench "nestedElement" $ nf (renderByteString . S.nestedElement) ""- , bench "parallelElement" $ nf (renderByteString . S.parallelElement) ""- , bench "listElement" $ nf (renderByteString . S.listElement) ""- , bench "Int" $ nf renderByteString (123456789 :: Int)- , bench "Integer" $ nf renderByteString (123456789 :: Integer)- , bench "Double" $ nf renderByteString (123456789 :: Double)- , bench "Float" $ nf renderByteString (123456789 :: Float)- , bench "Word" $ nf renderByteString (123456789 :: Word)- , bench "Proxy" $ nf renderByteString (Proxy :: Proxy "abc")- , bench "Char" $ nf renderByteString 'a'- , bench "oneElement Proxy" $ nf (renderByteString . S.oneElement) (Proxy :: Proxy "abc")- , bench "()" $ nf renderByteString ()- , bench "oneElement ()" $ nf (renderByteString . S.oneElement) ()- , bench "oneAttribute" $ nf (renderByteString . (ClassA :=)) ""- , bench "oneAttribute ()" $ nf (renderByteString . (ClassA :=)) ()- , bench "oneAttribute Proxy" $ nf (renderByteString . (ClassA :=)) (Proxy :: Proxy "abc")- , bench "parallelAttribute" $ nf (\x -> renderByteString $ ClassA := x # IdA := x) ""- , bench "elementWithAttribute" $ nf (\x -> renderByteString $ Div :@ (ClassA := x) :> x) ""- , bench "elementWithParallelAttribute" $ nf (\x -> renderByteString $ Div :@ (ClassA := x # IdA := x) :> x) ""- , bench "listOfAttributes" $ nf (\x -> renderByteString [ClassA := x, ClassA := x]) ""- , bench "listOfListOf" $ nf (\x -> renderByteString $ Div :> [I :> [Span :> x]]) ""+ [ bench "oneElement" $ nf (run . S.oneElement) ""+ , bench "nestedElement" $ nf (run . S.nestedElement) ""+ , bench "parallelElement" $ nf (run . S.parallelElement) ""+ , bench "listElement" $ nf (run . S.listElement) ""+ , bench "Int" $ nf run (123456789 :: Int)+ , bench "Integer" $ nf run (123456789 :: Integer)+ , bench "Double" $ nf run (123456789 :: Double)+ , bench "Float" $ nf run (123456789 :: Float)+ , bench "Word" $ nf run (123456789 :: Word)+ , bench "Proxy" $ nf run (Proxy :: Proxy "abc")+ , bench "Char" $ nf run 'a'+ , bench "oneElement Proxy" $ nf (run . S.oneElement) (Proxy :: Proxy "abc")+ , bench "()" $ nf run ()+ , bench "oneElement ()" $ nf (run . S.oneElement) ()+ , bench "oneAttribute" $ nf (run . (ClassA :=)) ""+ , bench "oneAttribute ()" $ nf (run . (ClassA :=)) ()+ , bench "oneAttribute Proxy" $ nf (run . (ClassA :=)) (Proxy :: Proxy "abc")+ , bench "parallelAttribute" $ nf (\x -> run $ ClassA := x # IdA := x) ""+ , bench "elementWithAttribute" $ nf (\x -> run $ Div :@ (ClassA := x) :> x) ""+ , bench "elementWithParallelAttribute" $ nf (\x -> run $ Div :@ (ClassA := x # IdA := x) :> x) ""+ , bench "listOfAttributes" $ nf (\x -> run [ClassA := x, ClassA := x]) ""+ , bench "listOfListOf" $ nf (\x -> run $ Div :> [I :> [Span :> x]]) "" ] -medium :: Benchmark-medium = bgroup "Medium"- [ bench "helloWorld" $ nf (renderByteString . M.helloWorld) "medium"- , bench "randomString" $ nf renderByteString randomString- , bench "randomStringRaw" $ nf renderByteString randomStringRaw- , bench "randomStrictText" $ nf renderByteString randomStrictText- , bench "randomStrictTextRaw" $ nf renderByteString randomStrictTextRaw- , bench "randomLazyText" $ nf renderByteString randomLazyText- , bench "randomLazyTextRaw" $ nf renderByteString randomLazyTextRaw- , bench "page" $ nf (renderByteString . M.page) "medium"- , bench "pageA" $ nf (renderByteString . M.pageA) "medium"- , bench "attrShort" $ nf (renderByteString . M.attrShort) "medium"- , bench "attrLong" $ nf (renderByteString . M.attrLong) "medium"- ]+string :: Benchmark+string = bgroup "String"+ [ bench "randomString" $ nf (run . (# randomString)) (1::Int)+ , bench "randomStringRaw" $ nf (run . (# randomStringRaw)) (1::Int)+ , bench "randomTextStrict" $ nf (run . (# randomTextStrict)) (1::Int)+ , bench "randomTextStrictRaw" $ nf (run . (# randomTextStrictRaw)) (1::Int)+ , bench "randomTextLazy" $ nf (run . (# randomTextLazy)) (1::Int)+ , bench "randomTextLazyRaw" $ nf (run . (# randomTextLazyRaw)) (1::Int)+ , bench "literalString" $ nf (run . (# "ASCII: aeiou {v{H5@!(c@i/e^93q7+.8?u)c:F?&_*jQ:{s-G[MIO*!.F$%dXDROgf3{Sts6zR)RT\\RM#5^~3/uKGCb2i,\\EXMN;hb0CJ/?9s4KHet-Fr-kV9H~T<RLpzQ9IV3OJexSv*QFk !%Ebyg4[$0{~-{{SS7nn(!D@LbOi-)Etz'z@H+s]VJ!'a>_:UJ7^zxZt=1*JdEF%U wPzEb!$GN7v.b?k99^(il6*a!Z/$bbHhv.8sor lm1j\\i\\;BBlD|sOSwm,f9hrc3rtpR454Lmqi0!'Xfk>L>;*%a(.W+tT)4f/yOHR_.Vscl3DIkeNs8s84B4WfzL&1^oiL6|Iv{4)v7&j_Y2)KYGp_\"`e#B{.TYqFyrXinq1*/=JTquF,*_pY`tdoi2~(?bZqS?i$5fSVmIE6/FW/F=^`5=.=v#\"]+{lw/(VUvY$'kOld,M'rKQY\\fO}+G|n-!X\\5@8L0C|hUMj5/8Mq`Rzg#j;VCmd}[+*wPb>{$?1e|0xZ\"'u?YWx7\"]>,gK^GgJ_F5ea1@e'{ K37nSU[h8_[K<kvAKA2+_&O}Jh-pxQqxS{78ZS9EBp_54vnjs@~>raHm)R> @Rht{je~,^7'9m8*O;2}x'{Z/B5l$~+jV.br@tFrFf?C1,[1fkjPzK?f.GP4 y-d)=#n'+99B0$V^^flg`AA9YlQ4t<gZ(8]JKyJz9OE$&oTY*?[N!Xf?d.Xm5\\-lC/!h$dqmh%{6\")B=oh/$4vQp3mvu`}rg] lwtyF5@nik&Tqn{}I_@$E!fa*8PmOGU6i06s,}NbW!8bH+gm1Zd,~du@>:Om.',9D2:c%i~YXNyJ2cQg=SVb34~c).1@U7'?_*JMkZWMpgO)&P(_QMAyolbwb%+Ep!?j;tcjEat>g>u97tfQ bNU#A783O1=K@)C;BW 4XlHor4}alsfCW[!3<=;(9fIeBE=AHd,`k!<V3-`fyP`3[4\"2 d,o(b<dZ4uMPY'bW8DT<T0&jFFg5dJ?hs23NLqBf+0RAfrj&RW3t]FI[xQh8L^6fYS&w`'N\"iSYTG%MR\"g9Li6]GK.<yiRX)NZXvbj\\-!if=@{J=\\T;GsE#(*/qy3v-7b]EYNScTsO:wH9vq0aybQuF+}H&],pp(S8tmh;\"^Q*&+ea`[45Zz'Wfn4-Ot=&;LmHfcta^b`@2xxg^B~k./o:ox-!(O:hmynqMhrJN~Fl82>q94D8d^|v^B?(O;G*b|Zt_#!pdM[qD8Ki>fnNzRGY*;1oI{><!``Lj8Y@\\%G%|!v KU)!.7U@kM!kdE>?Kad4b6XUq^MmF=r+P\\VuP78*-stkdnA%;ogs\"2d&#+fu8F9BXE(h%o,aoy$oufM\"(CGaO+lZqEuQ{`LL#b}Cog|y^N{WL*'1`KXHBS&13#ZEdvHE?:${N/wM ^}m40qaX6Qt_+aOu~6L,La rHkaEu\\%tDYLGHj3\\Yso7o\\rx%,_F^znD*}*mv9I$$\"}jg2ZP#f ,;*9|\\xi^{|;2)KtbM=U?Zr_:gI$OoXngAQ4ec.>d7>~1.W{OI.Rn*cMO4 3 CLR>h%c:C`\"J{0tX,V9f2!b;nIjP3;!(\\?G.dV`uI8!\">N;yoN9@;IVFg@w{l.h7K{zbQn^,=v[_%y[IdO3If#gGZ/WtDsAus!3>RymX>D-G7^hI~wj!'@w`CFN88Z_2p1NKC@iW-UB8S9kk.EWgTrWJe=s{g`:[{kn<J,I_C}ti.y5]0|qnfGjTCLK moKExUlh]kiM\">.bRIn^gM1y,u#RA|VOO,Ay39<voplYY:AR'_ovZ%6~@aI<AJt1Ms+/qd)]Mo9Te 8$k>tB&YkxopGc*tQT`y*\"rv\"!3l<lY.=j/%P>\"rsHfYkaMBZ+%HJ-'sl( |Puq\\dM{H% Wr:\">b1<|}7c#+Q]L,>*WU2(%~SBGiS6u[yB2iaYmV23b&c0BFbn\"c1/Gf;`1\\uKGw\\,tj#fsx+73*am~^>f/GwQ75-\"/]C*|e`ys}]]XfdZcg0>AseXE:*B5&.)^9@:$j0f;eeN6,j7{Q|K'6O<L6+}?eE,Dziy5I#b4xUKn0P[1(xkxG_Nf6(Qv$.B\";iDT_WYzcx1zrkSQAcAjG9Z:4(.|`uH5@r$8 h&gf wr!}.f\\/I4h-&~-lm`cBhaD8z9d!Sn|l}!wM].;5Lb<)<gNGcc-J.)3l=oJtQ/,>n-#\"Rav0a=LTUX9mIkH?Y$^a}U|LwOGa}3w3q7iB.cs}:up/*)#Fny34()\"ebt!]J7K,nZ8tOC,48\\gs;P]H+qWHWm\\LCy'6$pNLM}^haz&H(z[[EIXrBxHYD`5i17 )>$oDK\\xe:OEny6B}F`%7CR|k4G\\I?r~s(o:?\"(}s4{VT9+id@N:bzFC E[&%N}2G+VMbv}XC[BZ[kJ]V=gL-Ph](TVe,vpzaK7B0+K|c<:n0mSm3.:2U,j4cwZP1U1d{:5SWf(f[NXXM~7-_bk%oK{O@I|5U)o<zjE#Yy4~\\>n,\"-mC!uLF*`Pw\\vIOS7XJ.h~]t^^9CY#3H-1]g6s,_g_RyU-9TqccG3V)aa_}0IinfD6|?2+vQyRj_Q<s\\nh33^P+\"{RPOBr.?R4?(=dFKHP4bc6yfrgRQs*NyY(v;&UAgN`Z!yq\"4R940ksl[-WA]nk|4TPz1N|5bFhWC-q!+D.='B]d$3|w^)[_dB%((W!t=ToZ{0\\GP'&R^s*~0`28r)7Mkx@NfJ#cUGS9J|,rPFTj> mWIAJBzw(/,OSB?xD&b}S}?? yX1!PDYWd.%!k@(:=hJZ%{.|;-ENBE>t$Z!,cr3J6:Rs;;.[}(OA$C(dh;?\"iC- \\ J?:+RBEdHQ`nj>.sS#4zXMwbSQRlNXAjz9C#:w~Yk&iYh)ZZz{RC99~6HWJFl:lFLxbgb=z,+l$P \\|Ak8UGx]64h.V_ Eg*cR9)D`G7{r5~XJ:lk0K'#~bIam9w'L'-l(xP`tz:9*3f/ROz9EM=MW2Yd~q!\\'47]3p]KR@.nniZ8l,{5HU>EUQxRX(V n:EcL_h<u<YU-D5C~c?<>Lj#3V;yl*2czy~b ch}_[2,|j9D|HJS%em-=;'h;hqF$eDH]h<fh|s$_!r5{HRQu#g{q;xb?Q3s?!4:+K(EEds:p(idYI+a<.1'{7M!`$B],i-3p;w}~8lWkFL#\"~MVP/_R?yIoTarf 9vqgvH%$ArC)e'.(DAcbwG/'W|BQIO}|?Dc^QE%ukdj~[z]okuGXzP!IBT>DbtxgRjM=Je08AV9y-~gZ $KN_o=&@$qwE]^?D_'I5t3\"yS:_$\"'sC 9!Wvzh?58Ax5h `DQO/\\bG`t2!7_Fj#%qC%5+cA9-m9Xu*$`M4gJ\",5#*1:i=|]{i'pf:[hOTH7l#H~lKQfDjK/NyFV:ZM+HJ{W\\[4S!*lFP5-@sMsJW%,`'!J4[Jcs0WG/&|0)CBugj4fr,$-.<$NV,aGX4 @XrKga!`t@H.9x1PQ:9e^m8e3CiTT/wR^vEB+]?yGw.so(%>ZaGNn|@`ffeI>HoPBO&2L'3FMyI\"'BdObllKr8]D\\t(S&>`VXo2G.H#E`T'M3GQ3+6f:h^Na^5tBA1BV<]$]-K;ENy)\"7Y-4a|K57oeTE^b%.zkG[87vD 6#^[8*%SrSbg%;5*M{?s|vV{8\\)TPKZq']-j^wMQsu.-]_[r*<+hzZ@v:M::z3CqM]prE!8!e7D~-N>,FLb~ lA3GAC:\"oE}?m4hq'nfJ.=BQL#dyl/Qhw2bmgWt=JX_]FM3rSgJ2Hg`3?41R%\"\"iN[MD;O4-xX8B3L,F+9g! iEZ[3(97qQ/(pGZzY:BY8$ps#E`j}Trl~lyIrj{`'VDraHaMN-Y]%V\\U:tQ*m1W)V}|''-8wIBQ(01u|5_,.ZE3g@m9\";q_AbOa7TvelHS/|(tfJBm1KBBct+c}<#S}`?p>0)b^p)]4E\\*j3I`?L_~Oqhmh#*:,meS)Z<{~'~1],51n itIBtO+enEm}nH35ckS?^*hzv\"(~`AA|i\\emYgM!N40Ll@=)8AL[j<FM7+o|:e)**;w]XEE_3#,:on%_K,!TQ25ucrWoz_[Hs>:)^wkN?Qw+Fw,{aGORlUn`%g%)\",PW.y@#w`\"H,e#D^9WeGOP3: r:X(Tq35[as%\\r6{lC1$cx9NX\"FhjS -1ZksJrkoBFZbK4P^@~wm`RZ/@&i?~lv[1=A[Y!VlcfC(m=jL\"/=.aTkv{ W=s:xEcKO/^LA@o'[`C^*Iga/<'Rs\\:O!-&,xpZ-tPZY0H'rb*Ja\\.Ok2jl)$::\\|p#|9;goJ<'^7E^t(W~S@dKIg_KwlP:\" 7l|s$-hP^Hit<s~e6GGCF3:L<+-fEKmqS5eQ=,.Y\"@&PYtP>~Dzr,'zh.2A& 8,<Jx*2Zg(Ox_Myg[?0\"6V<,U~:(\"Rr{/^*&AFs2UMyL:gE(V,.8.@U*e8V5&E6fcfZL%=&b^3fE8\\+#r<fC'&0E)9'A`}3!O{TONVI:BP{3;3W:9z6b<4g=42jhPS>]}Xb!p#GS[^#F}gFPxm|5pfjj=t?FYU37#ABC4`S@[UU0*r|_F`!1;QL@K,>G53t_S\"Y{f;#4*&wnJ%V-$+P7Az}k8Fqw=cxH!R^h]w:Ydgn<12h$Hvx!qV#&`{*@\\5yFdi\\HYX$*ij2R5MU_ExkuqG1}}T&66zrFC@R#%]ml{\"j&^&V[kq56A3-.4>G6( @7-\"7Q3lDm),lvL2P|b5$$+#L&fcWfwNv9Wwn4}S'j%urMWceqOmZ&sO)Id}wY&Ak#t-ut^Ci^wnR5eS6ez4{P|k/TjrdK@|7KF$9~Q)Eso@C2m(*&2sf[J4 Pl`uzm3CfZ=XRP0L&FhPDC#$aP`~teiQ6A8p/mOIBN{2J!0e4qrLSUpvRl<2-AK($Lwa%e2)xBhZ9Lt[fL%7\"Vp~$[WA=,?:2Jb3h$uwvPA4V&b{tTVS rhdI\\c][:ba&o\\;2YSNg gz,8@/.Kvsjp+OI6zgInKS~vh,*F]v3v.4~:m;i#5E8aYc]J)B:`K.N[;Zo>hGoF>S29G4/+oQ/i>OXxn^%i$O}|SI\\!'z@wSKCe2]Fj$[L\\YDDvs{}|%i uou6i]\\n5=Y+==FJIpjBi42[|*x(IZ.Qt8(w^qD+&<f^Wkk:f7:_G$a:<B,]*W3SsoD&)ze&h;rf<Iy6&ECGVN'?0Nskh q HG=|}zNEshQtp6b41HP+]M((62(f1eB\\Ug)Qs-K].\"`g}Lj#h|4D`L*q$*OcD3)(HD60(f3h?ie=t]7(L8@^];H[To%n|uT''Xkf~Ls{y<0Z\\O(rq9Vgr_%,O*GL}eDb:Q/zB$6%RX#1_uLo:o#F)G@H|*Zu!{B..zC$7qSwhR!&OeR[4o&V88VB]_QZp0:8sBsz+12OQrr`wqKv6GM>1RS#/E998/gc]L.{2/$#$D+:J4x.}WEK3l c|-=>g`q*Y%P..8j%XYpl&n`8,^/?d$m`*0$\\BY_u#pW7f\"9;bvibvZYd$dT++K1tI*TmF{7B=b&N\"{SV:^U2\\h\"7+Ky_p&,2K!hk;61]X<l-o4$=,NuI*G!T_OXI((('QIW:}7uGoU6,U!{QQPi[9z$aKv~.=ZS9m4-NJrReG6h1*^'E?]v83=3$cS(>C!BFb4f(\\XkOCcHSJ<)It5dI+2r~8-eLY20&<\"~`v,uPq3\"Z8$1^B{%R*o$X4$$G^j\"I/*O.&`n)j,53#axtjx\\S%+12,##~L7[|wH?^%uUR}Ow&U/.&iy)#I|KD:\"K[!z:d1$;>~_5,[b?s?$^qen;O|4vf/P<:aShNx#S:^VS5sikFU>~ BObjd+\\j`(@0SQs`,a-*E`!GtxOe'n 0t[OL>'s`3^~[fCUY<_|IaEasw:wD5FV9R'0X43Y}]RDjl,&aq#6i|s_`g=PM^V9yk$@Fvy?MN\\9wdtYt#.kqR2G8i?ND;LqMU?d'L3~]#x{KT\\rNkl7;_ceL}{B-~6$jt}~ZTP/RwwI\\`l6dVN{D1 tkc|8!ATe$@ohoX)z*<ZK~]S2R`F&:0hUn3L<P8l0 M?j\"UubIn.1=b$eogi~I,ydIh4wnw|5y,bQD?Y(:Cx2a?bfi<2h'd*$@!/{A,VFM&]b''j(7r.tc%`F+|LN4B2dUx/)of[HP.(hV%K-g&;nwwG 3'RRAEK\"81[F5@JCd{D`T~&YeS-m8m?j0n)Cb@*HO_&)i<O+U=QQ0<}T|3QO&ReY/gxkto8Jzf%w^'l/4,z,Vykd@ I@IS{ tH7t,7p(OJpZ-DPPFM{5[ngaFk/^~'IE_mlR%ayA*?f HjD5/.XD&+rr/lK*1m;^ObyB+hjl d$23m*i\\6Pu[:4ZG\"- ~8GrGRd>$nM]U0tiahQo7^`pR},\\9.2Vt00Op.hhL+o}@h{aKg+1LDhyG5$n[0sxwFzH;%{&^5O`Z)LozW.Lu<n/rz$1@9| ~t*?L~HHx9:]<BAEV]u/Kb^/=&H?nfUyCa1y&A7xaAJ%E(C=xEB%l<'4GMbq`i_!'WUR~++ ln/u'h9 kzw\"Q's?z7*{p2=iHz\\JoK^jA=TGVe~NY3nl[T)'0`2W^7hEnds8N$$g?qgig]VV`nI#)g!Ck?7\"S3\"-HjHre:\"2cX}pH1u@tk^c=Bm`?6#cOhbD/&R[Z*X)$hal+M@\"$ hj;GN;e8),CQV0 `=itZYz\\2oY5EFE@T.~4L}uoo%%:|;/4A59p0&W--zA}~@*4<6af\\6fY7 h8^jeYc\\em=C4'[dl.eMcy;eiAmD]GH\\I~h&R`?<%L)I+%R@\\eyvQu&0zyh3&M_7`&o%)Y^7TqN!BiHTR*pT`&{RR@Nub4yd=FG\\a5=e$HNO_(WB#?@kak S'ubUEw1vL~!VaMxa~r?sG)\\A Y3W.s*=/Mf.R'8:.&cTX=('qzE-{?->Vy/l`Dt}Cfz,+[vu\\~z.\"Z!8tqKmW4eRZfFiyw[@'X?Um(w A:iR?bL]eK%lp=|{K0]qdn,B:t)e]yEDwn!/Xsw:6w0hwK2iH|e&sy$61eja8cWQ~?UN..p|xA3Jm`~j9(w#&#Qv5*5Cbt$N2hF!]EKLE~iePo$,I5hf,/n<cL0\"gP!J\\sRL~+ 3[?Zl,AGd0ZOCDL0O_+vLcAJS^$ IxpR>v-8e{\\Rhza],.AtQY@oB,,E5.VIWh#@k`0v6}WB~A|6tLzG\\A.V:cOcGy-d2XBj4OUN;?7}mj{Cl*]bs8+#PKbU$?+qp=jcguw%BGC`}'orA:*&Cxnaf'3AI{7cLzE@SCrBYskD!2wDENR13zb>xQO/:k+[i<Xt}<Yunq{z3(Qk!\\a]J\"QB5m;]31nojJ4XT|z{|(&a*H}Qw0\"9rMv+#<TvXf{\"5fk+!rRAL9B)`s#3$FY&& m|o4AT;ROjnjzq\"Y/y<9\\nc3A,_Y\"40p\\{K[MY==g`SjhNv8b<C 6`WvY\\ssYd_2Q] a9D`35gH*2\\2/|JxC4&kLp\\~G97V)G\\C+i-mzz\\vW}xv~xYnad%q(Q?H0\\b?9xUz-'%yC>(MX%4t]\"~j0E$+=AD(o:e\" nj30,aD#7Y#M b JImD~&?vkq5mL@J1s]].y=FNjC-m$L9K/Jp6Y[Y2uU((\\8K$2]8X-[(m? (g!X3iQPv7Qj&+:D=[ ?WZ}X)<R/ttr Wu-Pe+5fRwRA@)Q@S:b}WAi}=d=yqfuNiP%o36f1Wjas5+BE0;50_K37czEEodwS2Y>+L-M&%>I'k>k88FBn^kJ\\`7}3W5w~(zI(JXrO=lO#j%/2<jrO=x!|TN|qH!:NElrXM5C(/#7,q!AIlru[<*qgOs>4(TN\"]rMrMUGo%r?diYRhytsvp#Ec^,Yu-tN3c`$IEU^LI ,\"ca}I3/~E)LZkq</E0hFBLUTg9$6uG8^QT3#wO+w }:MP[W9cpF%.IF*Kv~Bp0)i&u&j4Z`~FN*pwWI=75_-$b]B:X`XPvjCXrP_qK*'-vXg,w a1)qm4u-])D@IuJV7:yryo'ql+uMI{3<3IW3CH\\UGJnsW;5]U8ZZ<9e>8,Pf7WGdYk/]K:WqU`8pk)%iL:=q[MFE)\\roWx<<=(JQB(NP=,%1P4ghND:bvk0Q>TL_%sm_ZN';W1&%(>-X*e#UT/^;,A$dsYP&XD6'^$hd>x-,o:M9.WfnA/js,*z2-80$N* $O*$Nm@Wky6H{VG'wVa[IP(]K5pfbxsy.w83Wg^~>_Ynr+:JEUU^rMm xy0nL,bgc|Qsj\\\\&[a{kY@'{Fzp'BM\\,#3Lm^pT&@ad].},efGo'jHH\\zYFM~&#+/5bH={1zjemX5wsJ$R|JiED l^(]r]4?_{H%e[D`~6^Dy^BnCDn>?WuF&RbsLVc{/E-ulm,CL+(i*AnlM4UQ%-L![j[y))uE!=$2hc[/25L8rWCGh/{,#3Ot[X:eOv\"JP'\\+m3h!&{7BJ>U^x09&g};]@j,1i2y>j&ly6+NB~%0JtC#)$^-?jV$ #gJjo(*[J_$=M1O`*~M`^jmgHi-iHw5BJ}m5f=]Ilc/WaVAO\"<]}%P!,0*N?8\\R[ZFkuL`A;%YsCNs^3/y48k65_@(iB|nW2)84f)+=up,3l(yvp|)GYli_EI*+j}=r`!M}[4v6uEG9|Q \\uB.U^@_<G+qjn\"z(gmd7L?=*TT;^=& O_kBGV=&8(udEpd-^D`]xXM?_I6I01+{a$bt--EAe5_mGo|rk/}+)I\"k\\7uGDYN*xb{!\\P.}q)NQ}!J\"_^$xnDy-RDtfoq8o}lT:=1di k%&OD1lj0Ig;uQ0rKM!on#QXur,(V>?C;-hi/l,]v<zxxI[SHZd S!+LL3]7IhxoL,u.|wgocv=8b8 %`?3^0MU9)5>-w{d^e*,}1k\\'%b9}6zv0k*ct2P]im:pq^q<5]6g)OU)@`JmA<2ot70=+p+0L4+Yfxs2`6Y$kTZgr?af2xq|0r4z6U'(MZY61\"|%veDF&M36UWv!,jx?4$jp,f%V VTO*0wy+33s-41&<!y5,.!\"5C*,}^3qNk:Q7&SXNBfzAEZbW\"m>8wzMvX(/OD^2W^sNfmlM{IRZk0F@.>3iNg_aXK#d[.`N|83@B'b4*N`k=[5e{ZF\"G`Mt#?N\\kmI14DNI \\b4dO>(.B]\\S*bM4}qS?.BjF^Mrm:VE4A-N^c'w)YvMs/;!ccv\"MC\\lfMQu`Yf*a[8*@9A}a/HuE J`Es{{N 22euv&P'$=`)x\\,vaV!a8*RR.^q/R_x> r:_z>j-y&;'r\\U&T?D(xKns%7MIE~6I$3r)u!+OWwmNRJy)bk^S.1>2UxyBK #VG&hX69/Do+Xx'.RHp1RH$i}_I%|]o;iGMuS'^DZgZ\\a.N9a?(U G_@)voP5\\y<*kyxE5o?-G>p,Gbe6n 9-n~)y\"zTF)@kR'|GRb7mj_m#%p-kEewK3DZIqJ(|&c2R{\"T=t'&B<ur&mzlF &?VV-#. b5^/*Ve9kVbN(w-]%jM~ Y|Xh?4?9jVq9S!Q;f-~J%MH>3!Nci!6`mTH^'pXxyLH.VnVeJE}4n3/\"xEc/K?m1wbCpR 1SIeMpA>m`sVSfJBjqH<[ZOB;z6~t\"DH}nY1N*;-FS$&~?Hu_:ayFm]XHKV,H\"<^R&=Vh;LE)!0/G.Up'/Oz+jNwiRo\"c&x']mi\\D\"OC3KF)wKz;|3POvt%9!q9&c!1?bnnhm?8#Z)JR$d'r]?'!mV0n8Yk,o8U'G%UR>W7@aPn-f|9UXL5tPe}3NSs!C.jC0Y!u]O5@@;w).Kt8n%5L ';,}i}9>)_{ K<0T~P+m7|Lp%!v]4jIi]!7[bZsg=&Q~7Qb/{0# MMn-acT!L$$Ra+q#p9uI0blW{pE^XRYZ.V}j9v:4b|@9JJe|~<&vurWNDt-|moga{TzzZQiD|1\"b{TaY[|x((305cwRE\\`k9I\\}%P}Zs\\|D bhdcN'Gi}*7Zg_,v%Q]Q*!?DbG0cK^G(e|&.iTmsrFvT#_ek(.!;k]vqJ$\\242& I8Z~FE5~k3Hwz8-Mj(B,YUcHcB6)U;HMTvA)aq 80WyT_n8/N/NQnv+9#j\\Ta\\*FlSk3{suX^SZ*vn h1u5]ubT>MtI`f5kH,&Q9eWD\\6\"p. kc;j|yjm'p81E*:|d)>W5;URa.~yWg+\"%)TZ|>)cv\"|*]IVg|fFstUh")) (1::Int)+ , bench "literalStringUtf8" $ nf (run . (# "UTF8: äeiöü {v{H5@!(c@i/e^93q7+.8?u)c:F?&_*jQ:{s-G[MIO*!.F$%dXDROgf3{Sts6zR)RT\\RM#5^~3/uKGCb2i,\\EXMN;hb0CJ/?9s4KHet-Fr-kV9H~T<RLpzQ9IV3OJexSv*QFk !%Ebyg4[$0{~-{{SS7nn(!D@LbOi-)Etz'z@H+s]VJ!'a>_:UJ7^zxZt=1*JdEF%U wPzEb!$GN7v.b?k99^(il6*a!Z/$bbHhv.8sor lm1j\\i\\;BBlD|sOSwm,f9hrc3rtpR454Lmqi0!'Xfk>L>;*%a(.W+tT)4f/yOHR_.Vscl3DIkeNs8s84B4WfzL&1^oiL6|Iv{4)v7&j_Y2)KYGp_\"`e#B{.TYqFyrXinq1*/=JTquF,*_pY`tdoi2~(?bZqS?i$5fSVmIE6/FW/F=^`5=.=v#\"]+{lw/(VUvY$'kOld,M'rKQY\\fO}+G|n-!X\\5@8L0C|hUMj5/8Mq`Rzg#j;VCmd}[+*wPb>{$?1e|0xZ\"'u?YWx7\"]>,gK^GgJ_F5ea1@e'{ K37nSU[h8_[K<kvAKA2+_&O}Jh-pxQqxS{78ZS9EBp_54vnjs@~>raHm)R> @Rht{je~,^7'9m8*O;2}x'{Z/B5l$~+jV.br@tFrFf?C1,[1fkjPzK?f.GP4 y-d)=#n'+99B0$V^^flg`AA9YlQ4t<gZ(8]JKyJz9OE$&oTY*?[N!Xf?d.Xm5\\-lC/!h$dqmh%{6\")B=oh/$4vQp3mvu`}rg] lwtyF5@nik&Tqn{}I_@$E!fa*8PmOGU6i06s,}NbW!8bH+gm1Zd,~du@>:Om.',9D2:c%i~YXNyJ2cQg=SVb34~c).1@U7'?_*JMkZWMpgO)&P(_QMAyolbwb%+Ep!?j;tcjEat>g>u97tfQ bNU#A783O1=K@)C;BW 4XlHor4}alsfCW[!3<=;(9fIeBE=AHd,`k!<V3-`fyP`3[4\"2 d,o(b<dZ4uMPY'bW8DT<T0&jFFg5dJ?hs23NLqBf+0RAfrj&RW3t]FI[xQh8L^6fYS&w`'N\"iSYTG%MR\"g9Li6]GK.<yiRX)NZXvbj\\-!if=@{J=\\T;GsE#(*/qy3v-7b]EYNScTsO:wH9vq0aybQuF+}H&],pp(S8tmh;\"^Q*&+ea`[45Zz'Wfn4-Ot=&;LmHfcta^b`@2xxg^B~k./o:ox-!(O:hmynqMhrJN~Fl82>q94D8d^|v^B?(O;G*b|Zt_#!pdM[qD8Ki>fnNzRGY*;1oI{><!``Lj8Y@\\%G%|!v KU)!.7U@kM!kdE>?Kad4b6XUq^MmF=r+P\\VuP78*-stkdnA%;ogs\"2d&#+fu8F9BXE(h%o,aoy$oufM\"(CGaO+lZqEuQ{`LL#b}Cog|y^N{WL*'1`KXHBS&13#ZEdvHE?:${N/wM ^}m40qaX6Qt_+aOu~6L,La rHkaEu\\%tDYLGHj3\\Yso7o\\rx%,_F^znD*}*mv9I$$\"}jg2ZP#f ,;*9|\\xi^{|;2)KtbM=U?Zr_:gI$OoXngAQ4ec.>d7>~1.W{OI.Rn*cMO4 3 CLR>h%c:C`\"J{0tX,V9f2!b;nIjP3;!(\\?G.dV`uI8!\">N;yoN9@;IVFg@w{l.h7K{zbQn^,=v[_%y[IdO3If#gGZ/WtDsAus!3>RymX>D-G7^hI~wj!'@w`CFN88Z_2p1NKC@iW-UB8S9kk.EWgTrWJe=s{g`:[{kn<J,I_C}ti.y5]0|qnfGjTCLK moKExUlh]kiM\">.bRIn^gM1y,u#RA|VOO,Ay39<voplYY:AR'_ovZ%6~@aI<AJt1Ms+/qd)]Mo9Te 8$k>tB&YkxopGc*tQT`y*\"rv\"!3l<lY.=j/%P>\"rsHfYkaMBZ+%HJ-'sl( |Puq\\dM{H% Wr:\">b1<|}7c#+Q]L,>*WU2(%~SBGiS6u[yB2iaYmV23b&c0BFbn\"c1/Gf;`1\\uKGw\\,tj#fsx+73*am~^>f/GwQ75-\"/]C*|e`ys}]]XfdZcg0>AseXE:*B5&.)^9@:$j0f;eeN6,j7{Q|K'6O<L6+}?eE,Dziy5I#b4xUKn0P[1(xkxG_Nf6(Qv$.B\";iDT_WYzcx1zrkSQAcAjG9Z:4(.|`uH5@r$8 h&gf wr!}.f\\/I4h-&~-lm`cBhaD8z9d!Sn|l}!wM].;5Lb<)<gNGcc-J.)3l=oJtQ/,>n-#\"Rav0a=LTUX9mIkH?Y$^a}U|LwOGa}3w3q7iB.cs}:up/*)#Fny34()\"ebt!]J7K,nZ8tOC,48\\gs;P]H+qWHWm\\LCy'6$pNLM}^haz&H(z[[EIXrBxHYD`5i17 )>$oDK\\xe:OEny6B}F`%7CR|k4G\\I?r~s(o:?\"(}s4{VT9+id@N:bzFC E[&%N}2G+VMbv}XC[BZ[kJ]V=gL-Ph](TVe,vpzaK7B0+K|c<:n0mSm3.:2U,j4cwZP1U1d{:5SWf(f[NXXM~7-_bk%oK{O@I|5U)o<zjE#Yy4~\\>n,\"-mC!uLF*`Pw\\vIOS7XJ.h~]t^^9CY#3H-1]g6s,_g_RyU-9TqccG3V)aa_}0IinfD6|?2+vQyRj_Q<s\\nh33^P+\"{RPOBr.?R4?(=dFKHP4bc6yfrgRQs*NyY(v;&UAgN`Z!yq\"4R940ksl[-WA]nk|4TPz1N|5bFhWC-q!+D.='B]d$3|w^)[_dB%((W!t=ToZ{0\\GP'&R^s*~0`28r)7Mkx@NfJ#cUGS9J|,rPFTj> mWIAJBzw(/,OSB?xD&b}S}?? yX1!PDYWd.%!k@(:=hJZ%{.|;-ENBE>t$Z!,cr3J6:Rs;;.[}(OA$C(dh;?\"iC- \\ J?:+RBEdHQ`nj>.sS#4zXMwbSQRlNXAjz9C#:w~Yk&iYh)ZZz{RC99~6HWJFl:lFLxbgb=z,+l$P \\|Ak8UGx]64h.V_ Eg*cR9)D`G7{r5~XJ:lk0K'#~bIam9w'L'-l(xP`tz:9*3f/ROz9EM=MW2Yd~q!\\'47]3p]KR@.nniZ8l,{5HU>EUQxRX(V n:EcL_h<u<YU-D5C~c?<>Lj#3V;yl*2czy~b ch}_[2,|j9D|HJS%em-=;'h;hqF$eDH]h<fh|s$_!r5{HRQu#g{q;xb?Q3s?!4:+K(EEds:p(idYI+a<.1'{7M!`$B],i-3p;w}~8lWkFL#\"~MVP/_R?yIoTarf 9vqgvH%$ArC)e'.(DAcbwG/'W|BQIO}|?Dc^QE%ukdj~[z]okuGXzP!IBT>DbtxgRjM=Je08AV9y-~gZ $KN_o=&@$qwE]^?D_'I5t3\"yS:_$\"'sC 9!Wvzh?58Ax5h `DQO/\\bG`t2!7_Fj#%qC%5+cA9-m9Xu*$`M4gJ\",5#*1:i=|]{i'pf:[hOTH7l#H~lKQfDjK/NyFV:ZM+HJ{W\\[4S!*lFP5-@sMsJW%,`'!J4[Jcs0WG/&|0)CBugj4fr,$-.<$NV,aGX4 @XrKga!`t@H.9x1PQ:9e^m8e3CiTT/wR^vEB+]?yGw.so(%>ZaGNn|@`ffeI>HoPBO&2L'3FMyI\"'BdObllKr8]D\\t(S&>`VXo2G.H#E`T'M3GQ3+6f:h^Na^5tBA1BV<]$]-K;ENy)\"7Y-4a|K57oeTE^b%.zkG[87vD 6#^[8*%SrSbg%;5*M{?s|vV{8\\)TPKZq']-j^wMQsu.-]_[r*<+hzZ@v:M::z3CqM]prE!8!e7D~-N>,FLb~ lA3GAC:\"oE}?m4hq'nfJ.=BQL#dyl/Qhw2bmgWt=JX_]FM3rSgJ2Hg`3?41R%\"\"iN[MD;O4-xX8B3L,F+9g! iEZ[3(97qQ/(pGZzY:BY8$ps#E`j}Trl~lyIrj{`'VDraHaMN-Y]%V\\U:tQ*m1W)V}|''-8wIBQ(01u|5_,.ZE3g@m9\";q_AbOa7TvelHS/|(tfJBm1KBBct+c}<#S}`?p>0)b^p)]4E\\*j3I`?L_~Oqhmh#*:,meS)Z<{~'~1],51n itIBtO+enEm}nH35ckS?^*hzv\"(~`AA|i\\emYgM!N40Ll@=)8AL[j<FM7+o|:e)**;w]XEE_3#,:on%_K,!TQ25ucrWoz_[Hs>:)^wkN?Qw+Fw,{aGORlUn`%g%)\",PW.y@#w`\"H,e#D^9WeGOP3: r:X(Tq35[as%\\r6{lC1$cx9NX\"FhjS -1ZksJrkoBFZbK4P^@~wm`RZ/@&i?~lv[1=A[Y!VlcfC(m=jL\"/=.aTkv{ W=s:xEcKO/^LA@o'[`C^*Iga/<'Rs\\:O!-&,xpZ-tPZY0H'rb*Ja\\.Ok2jl)$::\\|p#|9;goJ<'^7E^t(W~S@dKIg_KwlP:\" 7l|s$-hP^Hit<s~e6GGCF3:L<+-fEKmqS5eQ=,.Y\"@&PYtP>~Dzr,'zh.2A& 8,<Jx*2Zg(Ox_Myg[?0\"6V<,U~:(\"Rr{/^*&AFs2UMyL:gE(V,.8.@U*e8V5&E6fcfZL%=&b^3fE8\\+#r<fC'&0E)9'A`}3!O{TONVI:BP{3;3W:9z6b<4g=42jhPS>]}Xb!p#GS[^#F}gFPxm|5pfjj=t?FYU37#ABC4`S@[UU0*r|_F`!1;QL@K,>G53t_S\"Y{f;#4*&wnJ%V-$+P7Az}k8Fqw=cxH!R^h]w:Ydgn<12h$Hvx!qV#&`{*@\\5yFdi\\HYX$*ij2R5MU_ExkuqG1}}T&66zrFC@R#%]ml{\"j&^&V[kq56A3-.4>G6( @7-\"7Q3lDm),lvL2P|b5$$+#L&fcWfwNv9Wwn4}S'j%urMWceqOmZ&sO)Id}wY&Ak#t-ut^Ci^wnR5eS6ez4{P|k/TjrdK@|7KF$9~Q)Eso@C2m(*&2sf[J4 Pl`uzm3CfZ=XRP0L&FhPDC#$aP`~teiQ6A8p/mOIBN{2J!0e4qrLSUpvRl<2-AK($Lwa%e2)xBhZ9Lt[fL%7\"Vp~$[WA=,?:2Jb3h$uwvPA4V&b{tTVS rhdI\\c][:ba&o\\;2YSNg gz,8@/.Kvsjp+OI6zgInKS~vh,*F]v3v.4~:m;i#5E8aYc]J)B:`K.N[;Zo>hGoF>S29G4/+oQ/i>OXxn^%i$O}|SI\\!'z@wSKCe2]Fj$[L\\YDDvs{}|%i uou6i]\\n5=Y+==FJIpjBi42[|*x(IZ.Qt8(w^qD+&<f^Wkk:f7:_G$a:<B,]*W3SsoD&)ze&h;rf<Iy6&ECGVN'?0Nskh q HG=|}zNEshQtp6b41HP+]M((62(f1eB\\Ug)Qs-K].\"`g}Lj#h|4D`L*q$*OcD3)(HD60(f3h?ie=t]7(L8@^];H[To%n|uT''Xkf~Ls{y<0Z\\O(rq9Vgr_%,O*GL}eDb:Q/zB$6%RX#1_uLo:o#F)G@H|*Zu!{B..zC$7qSwhR!&OeR[4o&V88VB]_QZp0:8sBsz+12OQrr`wqKv6GM>1RS#/E998/gc]L.{2/$#$D+:J4x.}WEK3l c|-=>g`q*Y%P..8j%XYpl&n`8,^/?d$m`*0$\\BY_u#pW7f\"9;bvibvZYd$dT++K1tI*TmF{7B=b&N\"{SV:^U2\\h\"7+Ky_p&,2K!hk;61]X<l-o4$=,NuI*G!T_OXI((('QIW:}7uGoU6,U!{QQPi[9z$aKv~.=ZS9m4-NJrReG6h1*^'E?]v83=3$cS(>C!BFb4f(\\XkOCcHSJ<)It5dI+2r~8-eLY20&<\"~`v,uPq3\"Z8$1^B{%R*o$X4$$G^j\"I/*O.&`n)j,53#axtjx\\S%+12,##~L7[|wH?^%uUR}Ow&U/.&iy)#I|KD:\"K[!z:d1$;>~_5,[b?s?$^qen;O|4vf/P<:aShNx#S:^VS5sikFU>~ BObjd+\\j`(@0SQs`,a-*E`!GtxOe'n 0t[OL>'s`3^~[fCUY<_|IaEasw:wD5FV9R'0X43Y}]RDjl,&aq#6i|s_`g=PM^V9yk$@Fvy?MN\\9wdtYt#.kqR2G8i?ND;LqMU?d'L3~]#x{KT\\rNkl7;_ceL}{B-~6$jt}~ZTP/RwwI\\`l6dVN{D1 tkc|8!ATe$@ohoX)z*<ZK~]S2R`F&:0hUn3L<P8l0 M?j\"UubIn.1=b$eogi~I,ydIh4wnw|5y,bQD?Y(:Cx2a?bfi<2h'd*$@!/{A,VFM&]b''j(7r.tc%`F+|LN4B2dUx/)of[HP.(hV%K-g&;nwwG 3'RRAEK\"81[F5@JCd{D`T~&YeS-m8m?j0n)Cb@*HO_&)i<O+U=QQ0<}T|3QO&ReY/gxkto8Jzf%w^'l/4,z,Vykd@ I@IS{ tH7t,7p(OJpZ-DPPFM{5[ngaFk/^~'IE_mlR%ayA*?f HjD5/.XD&+rr/lK*1m;^ObyB+hjl d$23m*i\\6Pu[:4ZG\"- ~8GrGRd>$nM]U0tiahQo7^`pR},\\9.2Vt00Op.hhL+o}@h{aKg+1LDhyG5$n[0sxwFzH;%{&^5O`Z)LozW.Lu<n/rz$1@9| ~t*?L~HHx9:]<BAEV]u/Kb^/=&H?nfUyCa1y&A7xaAJ%E(C=xEB%l<'4GMbq`i_!'WUR~++ ln/u'h9 kzw\"Q's?z7*{p2=iHz\\JoK^jA=TGVe~NY3nl[T)'0`2W^7hEnds8N$$g?qgig]VV`nI#)g!Ck?7\"S3\"-HjHre:\"2cX}pH1u@tk^c=Bm`?6#cOhbD/&R[Z*X)$hal+M@\"$ hj;GN;e8),CQV0 `=itZYz\\2oY5EFE@T.~4L}uoo%%:|;/4A59p0&W--zA}~@*4<6af\\6fY7 h8^jeYc\\em=C4'[dl.eMcy;eiAmD]GH\\I~h&R`?<%L)I+%R@\\eyvQu&0zyh3&M_7`&o%)Y^7TqN!BiHTR*pT`&{RR@Nub4yd=FG\\a5=e$HNO_(WB#?@kak S'ubUEw1vL~!VaMxa~r?sG)\\A Y3W.s*=/Mf.R'8:.&cTX=('qzE-{?->Vy/l`Dt}Cfz,+[vu\\~z.\"Z!8tqKmW4eRZfFiyw[@'X?Um(w A:iR?bL]eK%lp=|{K0]qdn,B:t)e]yEDwn!/Xsw:6w0hwK2iH|e&sy$61eja8cWQ~?UN..p|xA3Jm`~j9(w#&#Qv5*5Cbt$N2hF!]EKLE~iePo$,I5hf,/n<cL0\"gP!J\\sRL~+ 3[?Zl,AGd0ZOCDL0O_+vLcAJS^$ IxpR>v-8e{\\Rhza],.AtQY@oB,,E5.VIWh#@k`0v6}WB~A|6tLzG\\A.V:cOcGy-d2XBj4OUN;?7}mj{Cl*]bs8+#PKbU$?+qp=jcguw%BGC`}'orA:*&Cxnaf'3AI{7cLzE@SCrBYskD!2wDENR13zb>xQO/:k+[i<Xt}<Yunq{z3(Qk!\\a]J\"QB5m;]31nojJ4XT|z{|(&a*H}Qw0\"9rMv+#<TvXf{\"5fk+!rRAL9B)`s#3$FY&& m|o4AT;ROjnjzq\"Y/y<9\\nc3A,_Y\"40p\\{K[MY==g`SjhNv8b<C 6`WvY\\ssYd_2Q] a9D`35gH*2\\2/|JxC4&kLp\\~G97V)G\\C+i-mzz\\vW}xv~xYnad%q(Q?H0\\b?9xUz-'%yC>(MX%4t]\"~j0E$+=AD(o:e\" nj30,aD#7Y#M b JImD~&?vkq5mL@J1s]].y=FNjC-m$L9K/Jp6Y[Y2uU((\\8K$2]8X-[(m? (g!X3iQPv7Qj&+:D=[ ?WZ}X)<R/ttr Wu-Pe+5fRwRA@)Q@S:b}WAi}=d=yqfuNiP%o36f1Wjas5+BE0;50_K37czEEodwS2Y>+L-M&%>I'k>k88FBn^kJ\\`7}3W5w~(zI(JXrO=lO#j%/2<jrO=x!|TN|qH!:NElrXM5C(/#7,q!AIlru[<*qgOs>4(TN\"]rMrMUGo%r?diYRhytsvp#Ec^,Yu-tN3c`$IEU^LI ,\"ca}I3/~E)LZkq</E0hFBLUTg9$6uG8^QT3#wO+w }:MP[W9cpF%.IF*Kv~Bp0)i&u&j4Z`~FN*pwWI=75_-$b]B:X`XPvjCXrP_qK*'-vXg,w a1)qm4u-])D@IuJV7:yryo'ql+uMI{3<3IW3CH\\UGJnsW;5]U8ZZ<9e>8,Pf7WGdYk/]K:WqU`8pk)%iL:=q[MFE)\\roWx<<=(JQB(NP=,%1P4ghND:bvk0Q>TL_%sm_ZN';W1&%(>-X*e#UT/^;,A$dsYP&XD6'^$hd>x-,o:M9.WfnA/js,*z2-80$N* $O*$Nm@Wky6H{VG'wVa[IP(]K5pfbxsy.w83Wg^~>_Ynr+:JEUU^rMm xy0nL,bgc|Qsj\\\\&[a{kY@'{Fzp'BM\\,#3Lm^pT&@ad].},efGo'jHH\\zYFM~&#+/5bH={1zjemX5wsJ$R|JiED l^(]r]4?_{H%e[D`~6^Dy^BnCDn>?WuF&RbsLVc{/E-ulm,CL+(i*AnlM4UQ%-L![j[y))uE!=$2hc[/25L8rWCGh/{,#3Ot[X:eOv\"JP'\\+m3h!&{7BJ>U^x09&g};]@j,1i2y>j&ly6+NB~%0JtC#)$^-?jV$ #gJjo(*[J_$=M1O`*~M`^jmgHi-iHw5BJ}m5f=]Ilc/WaVAO\"<]}%P!,0*N?8\\R[ZFkuL`A;%YsCNs^3/y48k65_@(iB|nW2)84f)+=up,3l(yvp|)GYli_EI*+j}=r`!M}[4v6uEG9|Q \\uB.U^@_<G+qjn\"z(gmd7L?=*TT;^=& O_kBGV=&8(udEpd-^D`]xXM?_I6I01+{a$bt--EAe5_mGo|rk/}+)I\"k\\7uGDYN*xb{!\\P.}q)NQ}!J\"_^$xnDy-RDtfoq8o}lT:=1di k%&OD1lj0Ig;uQ0rKM!on#QXur,(V>?C;-hi/l,]v<zxxI[SHZd S!+LL3]7IhxoL,u.|wgocv=8b8 %`?3^0MU9)5>-w{d^e*,}1k\\'%b9}6zv0k*ct2P]im:pq^q<5]6g)OU)@`JmA<2ot70=+p+0L4+Yfxs2`6Y$kTZgr?af2xq|0r4z6U'(MZY61\"|%veDF&M36UWv!,jx?4$jp,f%V VTO*0wy+33s-41&<!y5,.!\"5C*,}^3qNk:Q7&SXNBfzAEZbW\"m>8wzMvX(/OD^2W^sNfmlM{IRZk0F@.>3iNg_aXK#d[.`N|83@B'b4*N`k=[5e{ZF\"G`Mt#?N\\kmI14DNI \\b4dO>(.B]\\S*bM4}qS?.BjF^Mrm:VE4A-N^c'w)YvMs/;!ccv\"MC\\lfMQu`Yf*a[8*@9A}a/HuE J`Es{{N 22euv&P'$=`)x\\,vaV!a8*RR.^q/R_x> r:_z>j-y&;'r\\U&T?D(xKns%7MIE~6I$3r)u!+OWwmNRJy)bk^S.1>2UxyBK #VG&hX69/Do+Xx'.RHp1RH$i}_I%|]o;iGMuS'^DZgZ\\a.N9a?(U G_@)voP5\\y<*kyxE5o?-G>p,Gbe6n 9-n~)y\"zTF)@kR'|GRb7mj_m#%p-kEewK3DZIqJ(|&c2R{\"T=t'&B<ur&mzlF &?VV-#. b5^/*Ve9kVbN(w-]%jM~ Y|Xh?4?9jVq9S!Q;f-~J%MH>3!Nci!6`mTH^'pXxyLH.VnVeJE}4n3/\"xEc/K?m1wbCpR 1SIeMpA>m`sVSfJBjqH<[ZOB;z6~t\"DH}nY1N*;-FS$&~?Hu_:ayFm]XHKV,H\"<^R&=Vh;LE)!0/G.Up'/Oz+jNwiRo\"c&x']mi\\D\"OC3KF)wKz;|3POvt%9!q9&c!1?bnnhm?8#Z)JR$d'r]?'!mV0n8Yk,o8U'G%UR>W7@aPn-f|9UXL5tPe}3NSs!C.jC0Y!u]O5@@;w).Kt8n%5L ';,}i}9>)_{ K<0T~P+m7|Lp%!v]4jIi]!7[bZsg=&Q~7Qb/{0# MMn-acT!L$$Ra+q#p9uI0blW{pE^XRYZ.V}j9v:4b|@9JJe|~<&vurWNDt-|moga{TzzZQiD|1\"b{TaY[|x((305cwRE\\`k9I\\}%P}Zs\\|D bhdcN'Gi}*7Zg_,v%Q]Q*!?DbG0cK^G(e|&.iTmsrFvT#_ek(.!;k]vqJ$\\242& I8Z~FE5~k3Hwz8-Mj(B,YUcHcB6)U;HMTvA)aq 80WyT_n8/N/NQnv+9#j\\Ta\\*FlSk3{suX^SZ*vn h1u5]ubT>MtI`f5kH,&Q9eWD\\6\"p. kc;j|yjm'p81E*:|d)>W5;URa.~yWg+\"%)TZ|>)cv\"|*]IVg|fFstUh")) (1::Int)+ ] -- take 10000 . map chr . randomRs (32,126) <$> newStdGen +{-# INLINE run #-}+run :: Document a => a -> Word8+run = foldl1' (+) . renderByteString+ {-# NOINLINE randomString #-} randomString :: String-randomString = unsafePerformIO $ take 250 . randoms <$> newStdGen+randomString = unsafePerformIO $ take 10000 . randoms <$> newStdGen {-# NOINLINE randomStringRaw #-} randomStringRaw :: Raw String-randomStringRaw = unsafePerformIO $ Raw . take 250 . randoms <$> newStdGen+randomStringRaw = unsafePerformIO $ Raw . take 10000 . randoms <$> newStdGen -{-# NOINLINE randomStrictText #-}-randomStrictText :: T.Text-randomStrictText = unsafePerformIO $ T.pack . take 250 . randoms <$> newStdGen+{-# NOINLINE randomTextStrict #-}+randomTextStrict :: T.Text+randomTextStrict = unsafePerformIO $ T.pack . take 10000 . randoms <$> newStdGen -{-# NOINLINE randomStrictTextRaw #-}-randomStrictTextRaw :: Raw T.Text-randomStrictTextRaw = unsafePerformIO $ Raw . T.pack . take 250 . randoms <$> newStdGen+{-# NOINLINE randomTextStrictRaw #-}+randomTextStrictRaw :: Raw T.Text+randomTextStrictRaw = unsafePerformIO $ Raw . T.pack . take 10000 . randoms <$> newStdGen -{-# NOINLINE randomLazyText #-}-randomLazyText :: LT.Text-randomLazyText = unsafePerformIO $ LT.pack . take 250 . randoms <$> newStdGen+{-# NOINLINE randomTextLazy #-}+randomTextLazy :: LT.Text+randomTextLazy = unsafePerformIO $ LT.pack . take 10000 . randoms <$> newStdGen -{-# NOINLINE randomLazyTextRaw #-}-randomLazyTextRaw :: Raw LT.Text-randomLazyTextRaw = unsafePerformIO $ Raw . LT.pack . take 250 . randoms <$> newStdGen+{-# NOINLINE randomTextLazyRaw #-}+randomTextLazyRaw :: Raw LT.Text+randomTextLazyRaw = unsafePerformIO $ Raw . LT.pack . take 10000 . randoms <$> newStdGen comparison :: Benchmark comparison = bgroup "Comparison" [ bgroup "synthetic page"- [ bench "blaze-html" $ nf (renderHtml . (\x -> BL.blazePageA x <> BL.blazePageA x <> BL.blazePageA x <> BL.blazePageA x)) (fromString "TEST")- , bench "type-of-html" $ nf (renderByteString . (\x -> M.pageA x # M.pageA x # M.pageA x # M.pageA x)) "TEST"- , bench "compactHTML" $ nf (renderCompactByteString (compactHTML $ M.pageA (V @ "x") # M.pageA (V @ "x") # M.pageA (V @ "x") # M.pageA (V @ "x"))) (Put "TEST")+ [ bench "blaze-html" $ nf (foldl1' (+) . renderHtml . (\x -> BL.blazePageA x >> BL.blazePageA x >> BL.blazePageA x >> BL.blazePageA x)) (fromString "TEST")+ , bench "type-of-html" $ nf (run . (\x -> M.pageA x # M.pageA x # M.pageA x # M.pageA x)) "TEST"+ , bench "compactHTML" $ nf (foldl1' (+) . renderCompactByteString (compactHTML $ M.pageA (V @"x") # M.pageA (V @"x") # M.pageA (V @"x") # M.pageA (V @"x"))) (Put "TEST") ] , bgroup "table 50x10"- [ bench "blaze-html" $ nf (renderHtml . BL.blazeTable) (50,10)- , bench "type-of-html" $ nf (renderByteString . M.table) (50,10)+ [ bench "blaze-html" $ nf (foldl1' (+) . renderHtml . BL.blazeTable) (50,10)+ , bench "type-of-html" $ nf (run . M.table) (50,10) ] , bgroup "hackage upload"- [ bench "blaze-html" $ nf (renderHtml . BL.hackageUpload) (fromString "Uploading packages and package candidates | Hackage")- , bench "type-of-html" $ nf (renderByteString . ET.hackageUpload) "Uploading packages and package candidates | Hackage"- , bench "compactHTML" $ nf (renderCompactByteString (compactHTML $ ET.hackageUpload (V @ "x"))) (Put "Uploading packages and package candidates | Hackage")+ [ bench "blaze-html" $ nf (foldl1' (+) . renderHtml . BL.hackageUpload) (fromString "Uploading packages and package candidates | Hackage")+ , bench "type-of-html" $ nf (run . ET.hackageUpload) "Uploading packages and package candidates | Hackage"+ , bench "compactHTML" $ nf (foldl1' (+) . renderCompactByteString (compactHTML $ ET.hackageUpload (V @"x"))) (Put "Uploading packages and package candidates | Hackage") ] ] scaling :: Benchmark scaling = bgroup "Scaling" [ bgroup "2 divs"- [ bench "normal" $ nf (renderByteString . divs2) "input"- , bench "compact" $ nf (renderCompactByteString . compactHTML $ divs2 (V @ "x")) (Put "input")+ [ bench "normal" $ nf (run . divs2) "input"+ , bench "compact" $ nf (foldl1' (+) . renderCompactByteString (compactHTML $ divs2 (V @"x"))) (Put "input") ] , bgroup "4 divs"- [ bench "normal" $ nf (renderByteString . divs4) "input"- , bench "compact" $ nf (renderCompactByteString . compactHTML $ divs4 (V @ "x")) (Put "input")+ [ bench "normal" $ nf (run . divs4) "input"+ , bench "compact" $ nf (foldl1' (+) . renderCompactByteString (compactHTML $ divs4 (V @"x"))) (Put "input") ] , bgroup "8 divs"- [ bench "normal" $ nf (renderByteString . divs8) "input"- , bench "compact" $ nf (renderCompactByteString . compactHTML $ divs8 (V @ "x")) (Put "input")+ [ bench "normal" $ nf (run . divs8) "input"+ , bench "compact" $ nf (foldl1' (+) . renderCompactByteString (compactHTML $ divs8 (V @"x"))) (Put "input") ] , bgroup "16 divs"- [ bench "normal" $ nf (renderByteString . divs16) "input"- , bench "compact" $ nf (renderCompactByteString . compactHTML $ divs16 (V @ "x")) (Put "input")+ [ bench "normal" $ nf (run . divs16) "input"+ , bench "compact" $ nf (foldl1' (+) . renderCompactByteString (compactHTML $ divs16 (V @"x"))) (Put "input") ] , bgroup "32 divs"- [ bench "normal" $ nf (renderByteString . divs32) "input"- , bench "compact" $ nf (renderCompactByteString . compactHTML $ divs32 (V @ "x")) (Put "input")+ [ bench "normal" $ nf (run . divs32) "input"+ , bench "compact" $ nf (foldl1' (+) . renderCompactByteString (compactHTML $ divs32 (V @"x"))) (Put "input") ] ] where
src/Html.hs view
@@ -46,7 +46,7 @@ -- | Render a html document to a Builder. renderBuilder :: Document a => a -> Builder-renderBuilder = unConv . (render @ 'False . (T :: a -> T (ToList a) a))+renderBuilder = unConv . (render @'False . (T :: a -> T (ToList a) a)) -- | Render a html document to a String. renderString :: Document a => a -> String@@ -92,7 +92,7 @@ = uncurry MkCompactHTML . concatEithers . toList- . render @ 'True+ . render @'True $ (T :: a -> T (ToList a) a) html where concatEithers :: [Either Converted String] -> (B.ByteString, [(Int, B.ByteString)])@@ -102,7 +102,7 @@ go _ = [] f = BL.toStrict . toLazyByteString . unConv . mconcat . lefts indexVar :: forall a. Compactable a => a -> String -> Int- indexVar _ s = fromJust (elemIndex s (showTypeList @ (Variables a)))+ indexVar _ s = fromJust (elemIndex s (showTypeList @(Variables a))) -- | Show instances to faciliate ghci development. instance Document (a := b) => Show (a := b) where show = renderString
src/Html/Convert.hs view
@@ -16,9 +16,9 @@ import Data.Char (ord) import Data.Double.Conversion.ByteString import Numeric.Natural-import GHC.Exts+import GHC.Exts (build) import GHC.TypeLits-import GHC.CString (unpackCString#, unpackCStringUtf8#, unpackFoldrCString#)+import GHC.CString import qualified Data.Semigroup as S import qualified Data.Monoid as M@@ -78,12 +78,13 @@ instance KnownSymbol a => Convert (Proxy a) where {-# INLINE convert #-}; convert = Converted . U.byteStringCopy . fromString . symbolVal instance Convert () where {-# INLINE convert #-}; convert = const mempty+instance Convert Converted where {-# INLINE convert #-}; convert = id instance Convert (Raw Char) where {-# INLINE convert #-}; convert = Converted . B.charUtf8 . fromRaw-instance Convert (Raw String) where {-# INLINE convert #-}; convert = stringConvRaw . fromRaw+instance Convert (Raw String) where {-# INLINE convert #-}; convert = Converted . fromString . fromRaw instance Convert (Raw T.Text) where {-# INLINE convert #-}; convert = Converted . T.encodeUtf8Builder . fromRaw instance Convert (Raw TL.Text) where {-# INLINE convert #-}; convert = Converted . TL.encodeUtf8Builder . fromRaw instance Convert (Raw B.Builder) where {-# INLINE convert #-}; convert = Converted . fromRaw-instance Convert Char where {-# INLINE convert #-}; convert = Converted . BP.primBounded escapeUtf8+instance Convert Char where {-# INLINE convert #-}; convert = convert . T.singleton instance Convert String where {-# INLINE convert #-}; convert = stringConv instance Convert T.Text where {-# INLINE convert #-}; convert = Converted . T.encodeUtf8BuilderEscaped escape instance Convert TL.Text where {-# INLINE convert #-}; convert = Converted . TL.encodeUtf8BuilderEscaped escape@@ -94,41 +95,9 @@ instance Convert Double where {-# INLINE convert #-}; convert = Converted . U.byteStringCopy . toShortest instance Convert Word where {-# INLINE convert #-}; convert = Converted . B.wordDec -{-# INLINE builderCString# #-}-builderCString# :: BP.BoundedPrim Word8 -> Addr# -> Converted-builderCString# bp addr = Converted $ BP.primUnfoldrBounded bp go 0- where- go !i | b /= 0 = Just (fromIntegral b, i+1)- | otherwise = Nothing- where- !b = I# (ord# (at# i))- at# (I# i#) = indexCharOffAddr# addr i#- {-# INLINE [0] stringConv #-} stringConv :: String -> Converted-stringConv = Converted . BP.primMapListBounded escapeUtf8--{-# INLINE [0] stringConvRaw #-}-stringConvRaw :: String -> Converted-stringConvRaw = Converted . B.stringUtf8--escapeUtf8 :: BP.BoundedPrim Char-escapeUtf8- = BP.condB (> '>' ) BP.charUtf8- . BP.condB (== '<' ) (fixed4 ('&',('l',('t',';'))))- . BP.condB (== '>' ) (fixed4 ('&',('g',('t',';'))))- . BP.condB (== '&' ) (fixed5 ('&',('a',('m',('p',';')))))- . BP.condB (== '"' ) (fixed5 ('&',('#',('3',('4',';')))))- . BP.condB (== '\'') (fixed5 ('&',('#',('3',('9',';')))))- $ BP.liftFixedToBounded BP.char7- where- {-# INLINE fixed4 #-}- fixed4 x = BP.liftFixedToBounded $ const x BP.>$<- BP.char7 BP.>*< BP.char7 BP.>*< BP.char7 BP.>*< BP.char7-- {-# INLINE fixed5 #-}- fixed5 x = BP.liftFixedToBounded $ const x BP.>$<- BP.char7 BP.>*< BP.char7 BP.>*< BP.char7 BP.>*< BP.char7 BP.>*< BP.char7+stringConv = convert . T.pack escape :: BP.BoundedPrim Word8 escape@@ -151,19 +120,7 @@ BP.word8 BP.>*< BP.word8 BP.>*< BP.word8 BP.>*< BP.word8 BP.>*< BP.word8 {-# RULES "CONVERTED literal" forall a.- stringConv (unpackCString# a) = builderCString# escape a #-}+ stringConv (unpackCString# a) = Converted (BP.primMapByteStringBounded escape (fromString (unpackCString# a))) #-} {-# RULES "CONVERTED foldr literal" forall a.- stringConv (build (unpackFoldrCString# a)) = builderCString# escape a #-}--{-# RULES "CONVERTED literal raw" forall a.- stringConvRaw (unpackCString# a) = builderCString# (BP.liftFixedToBounded BP.word8) a #-}--{-# RULES "CONVERTED foldr literal raw" forall a.- stringConvRaw (build (unpackFoldrCString# a)) = builderCString# (BP.liftFixedToBounded BP.word8) a #-}--{-# RULES "CONVERTED literal utf8" forall a.- stringConv (unpackCStringUtf8# a) = convert (T.pack (unpackCStringUtf8# a)) #-}--{-# RULES "CONVERTED literal utf8 raw" forall a.- stringConvRaw (unpackCStringUtf8# a) = convert (Raw (T.pack (unpackCStringUtf8# a))) #-}+ stringConv (build (unpackFoldrCString# a)) = Converted (BP.primMapByteStringBounded escape (fromString (unpackCString# a))) #-}
src/Html/Reify.hs view
@@ -48,7 +48,7 @@ retrieve :: ([Builder] -> [Builder]) -> (Builder -> f) -> CompactHTML a -> Retrieve f a instance (KnownSymbol x, Retrievable xs) => Retrievable (x ': xs) where- retrieve m f (MkCompactHTML c1 c2) (Put x) = retrieve (m . (unConv (convert x) :)) f (MkCompactHTML @ xs c1 c2)+ retrieve m f (MkCompactHTML c1 c2) (Put x) = retrieve (m . (unConv (convert x) :)) f (MkCompactHTML @xs c1 c2) instance Retrievable '[] where retrieve m f (MkCompactHTML bs is) = f $ byteString bs <> foldMap (\(i,b) -> m [] !! i <> byteString b) is@@ -77,7 +77,7 @@ instance {-# INCOHERENT #-} KnownSymbol n => R 'True (T '[ "" ] (V n)) where- render _ = pure (Right (symbolVal (Proxy @ n)))+ render _ = pure (Right (symbolVal (Proxy @n))) -- | Common instances @@ -95,21 +95,21 @@ , R u (One (Proxy s)) , Semigroup (RenderOutput u) ) => R u (T '[s] (a := b)) where- render (T (_ := x)) = render (One (Proxy @ s)) <> render (T x :: T '[ "" ] b)+ render (T (_ := x)) = render (One (Proxy @s)) <> render (T x :: T '[ "" ] b) instance {-# INCOHERENT #-} ( R u (T '[ "" ] val) , R u (One (Proxy s)) , Semigroup (RenderOutput u) ) => R u (T '[s] val) where- render (T x) = render (One (Proxy @ s)) <> render (T x :: T '[ "" ] val)+ render (T x) = render (One (Proxy @s)) <> render (T x :: T '[ "" ] val) instance {-# OVERLAPPING #-} ( R u (One (Proxy s)) , R u (One String) , Semigroup (RenderOutput u) ) => R u (T '[s] String) where- render (T x) = render (One (Proxy @ s)) <> render (One x)+ render (T x) = render (One (Proxy @s)) <> render (One x) instance {-# OVERLAPPING #-} ( R u (T xs val)@@ -121,7 +121,7 @@ , R u (One (Proxy x)) , Semigroup (RenderOutput u) ) => R u (T ('List xs x) val) where- render (T t) = render (T t :: T xs val) <> render (One (Proxy @ x))+ render (T t) = render (T t :: T xs val) <> render (One (Proxy @x)) instance ( R u (T (Take (Length a) ps) a)@@ -160,7 +160,7 @@ , Monoid (RenderOutput u) ) => R u (T (s ': ss) [a]) where render (T xs)- = render (One (Proxy @ s))+ = render (One (Proxy @s)) <> foldMap (render . (T :: a -> T (ToList a) a)) xs instance@@ -170,7 +170,7 @@ , Monoid (RenderOutput u) ) => R u (T (s ': ss) (Maybe a)) where render (T mx)- = render (One (Proxy @ s))+ = render (One (Proxy @s)) <> foldMap (render . (T :: a -> T (ToList a) a)) mx instance@@ -180,5 +180,5 @@ , Semigroup (RenderOutput u) ) => R u (T (s ': ss) (Either a b)) where render (T eab)- = render (One (Proxy @ s))+ = render (One (Proxy @s)) <> either (render . (T :: a -> T (ToList a) a)) (render . (T :: b -> T (ToList b) b)) eab
src/Html/Type/Internal.hs view
@@ -1498,7 +1498,7 @@ instance ShowTypeList a => Show (CompactHTML a) where show (MkCompactHTML bs xs) = show bs ++ foldMap (\(i,b) -> "\n\ESC[36m" ++ vars !! i ++ "\ESC[0m\n" ++ show b) xs- where vars = showTypeList @ a+ where vars = showTypeList @a type family GetV a :: [Symbol] where GetV (a # b) = Append (GetV a) (GetV b)@@ -1524,7 +1524,7 @@ showTypeList :: [String] instance (ShowTypeList xs, KnownSymbol x) => ShowTypeList (x ': xs) where- showTypeList = symbolVal (Proxy @ x) : showTypeList @ xs+ showTypeList = symbolVal (Proxy @x) : showTypeList @xs instance ShowTypeList '[] where showTypeList = []
type-of-html.cabal view
@@ -1,5 +1,5 @@ name: type-of-html-version: 1.6.1.2+version: 1.6.2.0 synopsis: High performance type driven html generation. description: This library makes most invalid html documents compile time errors and uses advanced type level features to realise compile time computations. license: BSD3@@ -7,7 +7,8 @@ author: Florian Knupfer maintainer: fknupfer@gmail.com homepage: https://github.com/knupfer/type-of-html-tested-with: GHC == 8.10.2+tested-with: GHC == 9.0.1+ , GHC == 8.10.3 , GHC == 8.8.4 , GHC == 8.6.5 , GHC == 8.4.4