`Data.Text` vs` Data.Vector.Unboxed Char `

Есть ли разница в том, как Data.Text и Data.Vector.Unboxed Char работают внутри? Почему я должен выбирать один за другим?

Я всегда думал, что это здорово, что Haskell определяет String как [Char]. Есть ли причина, что что-то аналогичное не было сделано для Text и Vector Char?

Конечно, было бы выгодно сделать их одинаковыми.... Инструменты Text-y и Vector-y можно было записать для использования в обоих лагерях. Представьте себе веревки интов или регулярные выражения на строках покерных карт.

Конечно, я понимаю, что, вероятно, были исторические причины, и я понимаю, что в большинстве современных библиотек используется Data.Text, а не Vector Char, поэтому есть много практических причин, чтобы поддержать друг друга. Но мне больше интересно узнать об абстрактных качествах, а не о текущем состоянии, в котором мы оказались. Если бы все было переписано завтра, было бы лучше объединить эти два?

Изменить, с дополнительной информацией -

Вставить материал в перспективу -

  • В соответствии с этой страницей http://www.haskell.org/haskellwiki/GHC/Memory_Footprint GHC использует 16 байт для каждого Char в вашей программе!

  • Data.Text не O (1) index'able, это O (n).

  • Веревки (двоичные деревья, обернутые вокруг текста) также могут содержать строки... У них лучшая сложность для индекса/вставки/удаления, хотя в зависимости от количества узлов и баланса дерева индекс может быть близок к тексту текста.

Это мой отход от этого -

  • Text и Vector Char отличаются друг от друга....

  • Используйте String, если вам не нужна производительность.

  • Если производительность важна, по умолчанию используется текст.

  • Если требуется быстрое индексирование символов, и вы не против большого объема памяти (до 16 раз), используйте Vector Char.

  • Если вы хотите вставить/удалить много данных, используйте Ropes.

Ответ 1

Это довольно плохая идея подумать о Text как о списке символов. Text предназначен для того, чтобы считаться непрозрачным, удобным для пользователя блобом текста Юникода. Границы символов могут быть определены на основе кодирования, локали, языка, времени месяца, фазы луны, переворотов монет, выполненных ослепленным участником, и миграционных паттернов национальной птицы Венесуэлы, какими бы они ни были. Такая же история происходит при сортировке, обтекании, реверсе и т.д.

Это длинный способ сказать, что Text является абстрактным типом, представляющим человеческий язык, и далеко не в своем роде, чтобы вести себя не так, как его реализация, будь то ByteString, a Vector UTF16CodePoint, или что-то совершенно уникальное (что имеет место).

Чтобы прояснить это различие, обратите внимание, что нет гарантии, что unpack . pack свидетельствует о isomorphism, что предпочтительные способы преобразования из Text в ByteString находятся в Data.Text.Encoding и являются частичными, и что там весь сложный подключаемый модуль text-icu завален сложными способами обработки строк человеческого языка.

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

Педагогические преимущества type String = [Char] высоки, но практические преимущества довольно низки.

Ответ 2

Чтобы добавить к тому, что сказал Дж. Абрахамсон, стоит также провести различие между итерацией по рунам (грубо характер по характеру, но на самом деле может быть и идеограммами), в отличие от единичных логических кодов Unicode. Иногда вам нужно знать, смотрите ли вы на точку кода, которая была "украшена" предыдущей точкой кода.

В последнем случае вам необходимо провести различие между кодовыми точками, которые стоят отдельно (например, буквы, идеограммы), и те, которые изменяют текст, который следует (справа налево, кодовая точка, диакритика и т.д.).

Хорошо реализованные библиотеки юникода, как правило, абстрагируют эти детали и позволяют обрабатывать текст более или менее характерным образом, но вам нужно отказаться от некоторых предположений, которые исходят из мышления в терминах ASCII.

Байт не является символом. Логическая единица текста не обязательно является "символом". Не каждая точка кода стоит одна, некоторые украшают/комментируют следующую кодовую точку или даже остальную часть байтового потока до тех пор, пока не будут отменены (справа налево).

Юникод сложный. Существует не одна истинная кодировка, которая устранит трудность инкапсуляции разнообразия, присущего человеческому языку. Data.Text делает респектабельную работу, хотя.

Подводя итог:

Методы обработки:

  • byte by by by by by by by by by-byte - полностью недействителен для unicode, применим только к латинскому-1/ASCII
  • точка кода по кодовой точке - работает для обработки unicode, но является более низким уровнем, чем люди понимают.
  • логический rune-by-rune - то, что вы на самом деле хотите

Типы:

  • String (aka [ Char]) - имеет ограниченный объем. Лучше всего использовать для обучения Haskell или для устаревших прецедентов.

  • Текст - предпочтительный способ обработки "человеческого" текста.

  • Bytestring - для потоков байтов, необработанных данных, двоичных файлов и т.д.