Почему разработчики библиотек используют ByteString там, где кажется подходящим Text?

Работая над своим приложением, я столкнулся с проблемой того, что Aeson не расшифровывает ввод UTF8. Копая глубже, я обнаружил, что он опирается на Parser ByteString Аттопарсек, который, кажется, источник проблемы для меня. Но на самом деле это не то, о чем я здесь спрашиваю.

Дело в том, что это не единственное место, где я видел людей, использующих ByteString где, как мне кажется очевидным, только Text это уместно, поскольку JSON - это не какой-то двоичный файл, это читаемый текст, который может содержать символы UTF8.

Поэтому мне интересно, что я что-то упустил, и есть ли веские причины для выбора ByteString над Text или это просто широко распространенное явление плохого дизайна библиотеки, вызванное тем, что большинство людей меньше заботятся о любых других наборах символов, чем латинский.

2 ответа

Решение

Я думаю, что ваша проблема просто недоразумение.

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 значение, содержащее String, Show экземпляр для Char используется и экранирует все символы с кодами выше 127. Чтобы получить нужные глифы, вам нужно putStr[Ln] String,

Так aeson правильно декодированный ввод в кодировке utf8, как и следовало ожидать, поскольку он сам кодирует значения utf8:

encode = {-# SCC "encode" #-} encodeUtf8 . toLazyText . fromValue .
         {-# SCC "toJSON" #-} toJSON

Так что на вопрос, почему aeson использования ByteString и не Text для конечной цели кодирования и начальной точки декодирования.

Потому что это подходящий тип. Закодированные значения предназначены для переноса между машинами. Это происходит как поток байтов (октетов, если мы находимся в педантичном настроении). Это именно то, что ByteString обеспечивает последовательность байтов, которые затем должны обрабатываться в зависимости от приложения. Для целей aesonпоток байтов должен быть закодирован в utf-8, и aeson предполагает ввод decode функция действительна utf-8, и кодирует свой вывод как действительный utf-8.

Передача например Text столкнется с проблемами переносимости, поскольку 16-битная кодировка зависит от порядка байтов, поэтому Text не подходит для обмена данными между машинами. Обратите внимание, что aeson использования Text как промежуточный тип при кодировании (и, вероятно, также при декодировании), потому что это подходящий тип для использования на промежуточных этапах.

Стандарт JSON основан на UTF-16, а не UTF-8. Более подробная информация доступна на официальном сайте, http://json.org/. (И в дальнейшей защите Aeson двоичные биты JSON не открываются через его интерфейс: String конструктор Value содержит Textне ByteString.)

Другие вопросы по тегам