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

Почему Haskell по умолчанию использует строковый список связанных символов?

Тот факт, что реализация Haskell по умолчанию String неэффективна как с точки зрения скорости, так и с памятью, хорошо известна. Насколько мне известно, [] lists в целом реализованы в Haskell как односвязные списки и для большинства небольших/простых типов данных (например, Int), это не очень хорошая идея, но для String это похоже на полный перебор. Некоторые из мнений по этому вопросу включают:

Real World Haskell

В простых тестах, подобных этому, даже программы, написанные на интерпретируемых языках, таких как Python, могут превосходить код Haskell, который использует String на порядок.

Эффективная реализация строк в Haskell

Поскольку String является только [ Char], это связанный список Char, это означает, что Strings имеют плохую локальность ссылки и снова означает, что Strings довольно большие в памяти, как минимум, N * (21 бит + Мбит), где N - длина строки, а M - размер указателя (...). Строки гораздо реже могут быть оптимизированы для циклов и т.д. Компилятором.

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

TL; DR: Почему реализация Haskell по умолчанию String представляет собой односвязный список, хотя он ужасно неэффективен и редко используется для приложений реального мира (за исключением действительно простых)? Есть ли исторические причины? Легче ли реализовать?

4b9b3361

Ответ 1

Почему реализация Haskell по умолчанию для String представляет собой список, связанный со списком

Поскольку поддержка однопользовательских списков поддерживает:

  • индукция с помощью сопоставления с образцом
  • имеют полезные свойства, такие как Monad, Functor
  • являются корректно параметрически полиморфными
  • естественно ленивы

и поэтому String в качестве [Char] (точки юникода) означает тип строки, который соответствует языковым целям (начиная с 1990 года) и по существу "бесплатно" с библиотекой списков.

Таким образом, исторически разработчикам языка больше интересовали хорошо продуманные основные типы данных, чем современные проблемы обработки текста, поэтому у нас есть элегантный, простой в понимании, простой способ обучения String, который не является " t довольно юникодный текстовый фрагмент и не является плотным, упакованным строгим типом данных.

Ответ 2

Эффективность - это только одна ось для измерения абстракции. Хотя списки довольно неэффективны для операций text-y, они чертовски удобны в том, что существует множество операций с списками, реализованных полиморфно, которые имеют полезные интерпретации, когда они специализируются на [Char], поэтому вы получаете много повторного использования как в реализации библиотеки, так и в пользовательский мозг.

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

Ответ 3

На данный момент это, вероятно, исторический: оптимизация, которая сделала такие вещи, как ByteString настолько эффективными, в последнее время, тогда как [Char] предшествует их всем годам.