Текст або Bytestring


78

Хороший день.

Єдине, що я зараз ненавиджу в Haskell - це кількість пакетів для роботи з рядком.

Спочатку я використовував власні [Char]рядки Haskell , але коли я спробував почати використовувати бібліотеки хакерів, то повністю загубився в нескінченних перетвореннях. Здається, кожен пакет використовує різні рядки, деякі використовують власну річ.

Далі я переписав свій код із Data.Textрядками та OverloadedStringsрозширенням, я вибрав, Textоскільки він має ширший набір функцій, але, схоже, багато проектів віддають перевагу ByteString.
Хтось міг дати короткі міркування, чому використовувати те чи інше?

PS: До речі, як конвертувати з Textв ByteString?

Не вдалося зіставити очікуваний тип Data.ByteString.Lazy.Internal.ByteString з виведеним типом Текст Очікуваний тип: IO Data.ByteString.Lazy.Internal.ByteString Введений тип: IO Text

Я спробував encodeUtf8з Data.Text.Encoding, але не пощастило:

Не вдалося збігти очікуваний тип Data.ByteString.Lazy.Internal.ByteString із виведеним типом Data.ByteString.Internal.ByteString

UPD:

Дякую за відповіді, що * Доброта кусочків виглядає як шлях, але я був трохи вражений результатом, моя оригінальна функція виглядала так:

htmlToItems :: Text -> [Item]
htmlToItems =
    getItems . parseTags . convertFuzzy Discard "CP1251" "UTF8"

А тепер стало:

htmlToItems :: Text -> [Item]
htmlToItems =
    getItems . parseTags . fromLazyBS . convertFuzzy Discard "CP1251" "UTF8" . toLazyBS
    where
      toLazyBS t = fromChunks [encodeUtf8 t]
      fromLazyBS t = decodeUtf8 $ intercalate "" $ toChunks t

І так, ця функція не працює, оскільки вона неправильна, якщо ми Textїї подаємо, то ми впевнені, що цей текст правильно закодований і готовий до використання, і перетворити це дурне, але все-таки таке багатослівне перетворення все-таки має бути прийняте місце десь надворі htmltoItems.


41
Люди Хаскеля, будь ласка, мати уніфікований рядок :)
Анкур,

8
@Ankur: Textстає фактичною текстовою реалізацією. Рядок все ще існує із застарілих причин і з простих речей, але для серйозних маніпуляцій з текстом вам слід використовувати Text.
ivanm

2
@ivanm: якби лише всі ці застарілі бібліотеки, побудовані на тестах, рухались би конвертувати!
John L

1
@ivanm насправді трапляється так, що текст непридатний для використання, зараз я використовую декілька бібліотек (Database.MongoDB, Text.Iconv), і жодна з них не поважає Text, і, виконуючи всі перетворення вручну, не здається розумним.
Dfr

2
Як і де Ви оригінально отримуєте Текст? Причина, з якою у вас виникають проблеми, полягає в тому, що вам ніколи не доведеться перетворювати текст між різними кодуваннями. Вам слід декодувати текстові дані з правильним кодуванням, а потім просто використовуватиhtmlToItems = getItems . parseTags
shang

Відповіді:


68

ByteStringsв основному корисні для двійкових даних, але вони також є ефективним способом обробки тексту, якщо вам потрібен лише набір символів ASCII. Якщо вам потрібно обробляти рядки Unicode, вам потрібно використовувати Text. Однак я повинен підкреслити, що ні те, ні інше не є заміною іншого, і вони, як правило, використовуються для різних речей: хоча Textпредставляє чистий Unicode, вам все одно потрібно кодувати в і з двійкового ByteStringпредставлення, коли ви, наприклад, переносите текст через сокет або файл .

Ось хороша стаття про основи Unicode, яка гідно пояснює відношення кодових точок Unicode ( Text) та закодованих двійкових байтів ( ByteString): Абсолютний мінімум, кожен розробник програмного забезпечення Абсолютно, позитивно повинен знати про Unicode та символів Набори

Ви можете використовувати модуль Data.Text.Encoding для перетворення між двома типами даних, або Data.Text.Lazy.Encoding, якщо ви використовуєте ліниві варіанти (як ви, мабуть, робите на основі повідомлень про помилки).


Тут вдарили з іншого боку, тому що всі мої рядки вже є строгими: не вдалося збігатися із очікуваним типом. Text against inferred type Data.Text.Lazy.Internal.TextТому я знайшов fromChunks для тексту, добре, але остаточний результат поки некрасивий.
Dfr

5
Будь ласка, не використовуйте bytestring для "текстових" даних, навіть якщо все, що вам потрібно, це ASCII. Використовуйте Text для текстових даних, а ByteString для упакованих структур даних. Якщо ми всі погодимось щодо того, які типи повинні представляти семантично , у нас буде набагато менше плутанини щодо того, який тип використовувати, і, зрештою, менше перетворень між типами.
номен

1
"вам все одно потрібно кодувати до та з двійкового представлення ByteString кожного разу, коли ви, наприклад, переносите текст через сокет або файл." textПакет фактично надає функції для роботи з файлами вже.

1
Так, Data.Text.IOмодуль має функції для роботи з файлами, але вони майже ніколи не є тим, що ви хочете. Вони внутрішньо декодуються Textз ByteStringвикористання набору символів за замовчуванням для вашої локальної системи. Якщо файл має інше кодування, це призведе до помилки під час виконання або тексту сміття. Явне кодування та декодування майже завжди є правильним варіантом.
shang

26

Ви точно хочете використовувати Data.Text для текстових даних.

encodeUtf8це шлях. Ця помилка:

Не вдалося збігти очікуваний тип Data.ByteString.Lazy.Internal.ByteString із виведеним типом Data.ByteString.Internal.ByteString

означає, що ви надаєте строгий байтовий код для коду, який очікує лінивого байтового тестування Перетворення просте завдяки fromChunksфункції:

Data.ByteString.Lazy.fromChunks :: [Data.ByteString.Internal.ByteString] -> ByteString

тож усе, що вам потрібно зробити, - це додати функцію fromChunks [myStrictByteString]всюди, де очікується ледачий байтовий тест.

Перетворення в інший спосіб може бути здійснено за допомогою подвійної функції toChunks, яка приймає ліниве побічне тестування і дає список строгих фрагментів.

Можливо, ви захочете запитати у супровідників деяких пакетів, чи зможуть вони надати текстовий інтерфейс замість або на додаток до інтерфейсу bytestring.


5

Використовуйте одну функцію csз Data.String.Conversions.

Це дозволить вам конвертувати між String, ByteStringта Text(а також ByteString.Lazyта Text.Lazy), залежно від вводу та очікуваних типів.

Вам все одно доведеться зателефонувати, але більше не турбуватися про відповідні типи.

Див. Цю відповідь для прикладу використання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.