我认为你的问题只是一个误解。
Prelude> print "Ёжик лижет мёд."
"\1025\1078\1080\1082 \1083\1080\1078\1077\1090 \1084\1105\1076."
Prelude> putStrLn "\1025\1078\1080\1082 \1083\1080\1078\1077\1090 \1084\1105\1076."
Ёжик лижет мёд.
Prelude> "{\"a\": \"Ёжик лижет мёд.\"}"
"{\"a\": \"\1025\1078\1080\1082 \1083\1080\1078\1077\1090 \1084\1105\1076.\"}"
当您print
的值包含 aString
时,将使用Show
for 的实例,并转义所有代码点高于 127 的字符。要获得所需的Char
字形,您需要.putStr[Ln]
String
如此aeson
正确地解码了 utf8 编码的输入,正如预期的那样,因为它对值本身进行了 utf8 编码:
encode = {-# SCC "encode" #-} encodeUtf8 . toLazyText . fromValue .
{-# SCC "toJSON" #-} toJSON
那么对于为什么aeson
使用ByteString
而不是Text
用于编码的最终目标和解码的起点的问题。
因为那是合适的类型。编码值旨在在机器之间可移植地传输。这以字节流的形式发生(八位字节,如果我们处于迂腐的心情)。这正是 a 所ByteString
提供的,然后必须以特定于应用程序的方式处理的字节序列。出于 的目的aeson
,字节流应以 utf-8 编码,并aeson
假设decode
函数的输入是有效的 utf-8,并将其输出编码为有效的 utf-8。
传输 egText
会遇到可移植性问题,因为 16 位编码取决于字节顺序,因此Text
不是机器之间数据交换的合适格式。请注意,在编码时(可能也在解码时)aeson
用作Text
中间类型,因为这是在中间阶段使用的合适类型。