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

Текст или Bytestring

Добрый день.

Единственное, что я ненавижу в Haskell, - это количество пакетов для работы со строкой.

Сначала я использовал собственные строки Haskell [Char], но когда я попытался начать использовать библиотеки hackage, то полностью потерялся в бесконечных конверсиях. Кажется, что каждый пакет использует реализацию разных строк, некоторые из них принимают свою собственную вещь ручной работы.

Затем я переписал свой код с помощью строк Data.Text и расширения OverloadedStrings, я выбрал Text, потому что он имеет более широкий набор функций, но кажется, что многие проекты предпочитают ByteString.
Кто-то может дать короткое объяснение, почему использовать тот или иной?

PS: btw, как преобразовать из 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:

Спасибо за ответы, что * Chunks goodness выглядит как способ пойти, но я несколько шокирован результатом, моя оригинальная функция выглядела так:

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.

4b9b3361

Ответ 1

ByteStrings в основном полезны для двоичных данных, но они также являются эффективным способом обработки текста, если все, что вам нужно, это набор символов ASCII. Если вам нужно обрабатывать строки юникода, вам нужно использовать Text. Тем не менее, я должен подчеркнуть, что ни одна из них не является заменой другой, они обычно используются для разных вещей: хотя Text представляет чистый unicode, вам все равно нужно кодировать в и из двоичного представления ByteString всякий раз, когда вы, например. транспортный текст через сокет или файл.

Вот хорошая статья об основах юникода, которая делает достойную работу по объяснению отношения кодовых точек Юникода (Text) и закодированных двоичных байтов (ByteString): Абсолютный минимум Каждый разработчик программного обеспечения Абсолютно, положительно должен знать о Unicode и наборах символов

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

Ответ 2

Вы определенно хотите использовать 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.

Ответ 3

Используйте одну функцию cs из Data.String.Conversions.

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

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

См. этот ответ для примера использования.