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

Автоматическое преобразование между String и Data.Text в haskell

Как отметил Никита Волков в своем вопросе Data.Text vs String, я также задался вопросом, почему мне приходится иметь дело с различными реализациями строк type String = [Char] и Data.Text в Haskell. В моем коде я часто использую функции pack и unpack.

Мой вопрос: есть ли способ автоматического преобразования между обоими строковыми типами, чтобы я мог часто писать pack и unpack?

В других языках программирования, таких как Python или JavaScript, есть, например, автоматическое преобразование между целыми числами и поплавками, если это необходимо. Могу ли я достичь чего-то подобного в haskell? Я знаю, что указанные языки слабо типизированы, но я слышал, что С++ имеет аналогичную функцию.

Примечание. Я уже знаю расширение языка {-# LANGUAGE OverloadedStrings #-}. Но, как я понимаю, эти языковые расширения применяются только к строкам, определенным как "...". Я хочу иметь автоматическое преобразование для строк, которые я получил от других функций, или у меня есть аргументы в определениях функций.

Расширенный вопрос: Haskell. Текст или Bytestring охватывает также разницу между Data.Text и Data.ByteString. Есть ли способ автоматического преобразования между тремя строками String, Data.Text и Data.ByteString?

4b9b3361

Ответ 1

Нет.

Haskell не имеет скрытых принуждений по техническим, философским и почти религиозным причинам.

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

Мы можем автоматически преобразовывать литералы в Text с помощью OverloadedString путем десурации строкового литерала "foo" до fromString "foo" и fromString для Text просто вызывает pack.

Вопрос может состоять в том, чтобы спросить, почему вы так много принуждаете? Есть ли какие-то причины, по которым вам нужно unpack Text значения так часто? Если вы постоянно меняете их на строки, это немного побивает цель.

Ответ 2

Почти Да: Data.String.Conversions

Библиотеки Haskell используют разные типы, поэтому есть много ситуаций, в которых нет выбора, кроме как сильно использовать преобразование, отвратительное, поскольку оно - переписывание библиотек не считается реальным выбором.

Я вижу две конкретные проблемы, одна из которых потенциально является значительной проблемой для принятия Haskell:

  • кодирование заканчивается тем, что требует конкретных знаний об использовании библиотек, которые вы хотите использовать. Это большая проблема для языка высокого уровня.

  • производительность на простых задачах плоха - это большая проблема для обобщенного языка.

Реферат по конкретным типам

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

Для этой проблемы есть действительно удобное решение: Data.String.Conversions package, если вам нравится UTF-8 как ваш по умолчанию.

Этот пакет предоставляет одну функцию преобразования cs между несколькими различными типами.

  • String
  • Data.ByteString.ByteString
  • Data.ByteString.Lazy.ByteString
  • Data.Text.Text
  • Data.Text.Lazy.Text

Итак, вы просто import Data.String.Conversions и используете cs, который выведет правильную версию функции преобразования в соответствии с типами ввода и вывода.

Пример:

import Data.Aeson              (decode)
import Data.Text               (Text)
import Data.ByteString.Lazy    (ByteString)
import Data.String.Conversions (cs)

decodeTextStoredJson' :: T.Text -> MyStructure
decodeTextStoredJson' x = decode (cs x) :: Maybe MyStructure

NB: В GHCi у вас обычно нет контекста, который дает целевой тип, поэтому вы направляете преобразование, явно указывая тип результата, например, для read

let z = cs x :: ByteString

Производительность и крик для "истинного" решения

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

  • законно требовать преобразования, поскольку данные не изменяются;
  • Наилучшая производительность достигается за счет не преобразования данных из одного типа в другой для административных целей;
  • принуждение - зло - коэрцитивное, даже.

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

Nota: Я абсолютно не могу оценить возможности/потенциальные недостатки этой идеи. Могут быть некоторые очень звуковые пробки.