Текст или строка - PullRequest
       1

Текст или строка

76 голосов
/ 09 сентября 2011

Добрый день.

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

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

Далее я переписал свой код с помощью 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.

Ответы [ 3 ]

64 голосов
/ 09 сентября 2011

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

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

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

26 голосов
/ 09 сентября 2011

Вы определенно хотите использовать Data.Text для текстовых данных.

encodeUtf8 это путь. Эта ошибка:

Не удалось найти ожидаемый тип Data.ByteString.Lazy.Internal.ByteString для предполагаемого типа Data.ByteString.Internal.ByteString

означает, что вы предоставляете строгую строку для кода, который ожидает lazy строку. Преобразование легко с функцией fromChunks:

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

так что все, что вам нужно сделать, это добавить функцию fromChunks [myStrictByteString] везде, где ожидается ленивая строка.

Преобразование другим способом может быть выполнено с помощью двойной функции toChunks, которая принимает ленивую строку и выдает список строгих блоков.

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

5 голосов
/ 12 декабря 2014

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...