Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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 как промежуточный тип при кодировании (и, предположительно, также при декодировании), потому что это подходящий тип для использования на промежуточных этапах.

Ответ 2

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