web-dev-qa-db-fra.com

Data.Text vs String

Alors que l'opinion générale de la communauté Haskell semble être qu'il est toujours préférable d'utiliser Text au lieu de String, le fait que les API de la plupart des bibliothèques maintenues sont toujours String -oriented confond l'enfer hors de moi. D'autre part, il y a projets notables , qui considèrent String comme une erreur tout à fait et fournissent un Prelude avec toutes les instances de String- orientées fonctions remplacées par leurs équivalents Text-.

Y a-t-il donc des raisons pour que les gens continuent à écrire des API orientées String à l'exception de la compatibilité avec Prelude en amont et en standard et les "interfaces de commutation"? Y a-t-il éventuellement d'autres inconvénients à Text par rapport à String?

En particulier, cela m'intéresse parce que je conçois une bibliothèque et essaie de décider quel type utiliser pour exprimer les messages d'erreur.

69
Nikita Volkov

Ma supposition sans réserve est que la plupart des rédacteurs de bibliothèques ne veulent pas ajouter plus de dépendances que nécessaire. Étant donné que les chaînes font littéralement partie de chaque distribution Haskell (cela fait partie de la norme de langage!), Il est beaucoup plus facile d'être adopté si vous utilisez des chaînes et n'exigez pas que vos utilisateurs trient les distributions de texte du piratage.

C'est l'une de ces "erreurs de conception" avec lesquelles vous n'avez qu'à vivre, à moins que vous ne puissiez convaincre la plupart de la communauté de passer la nuit. Regardez simplement combien de temps il a fallu pour que Applicative soit une superclasse de Monad - un changement relativement mineur mais très recherché - et imaginez combien de temps il faudrait pour remplacer toutes les choses String par Text.


Pour répondre à votre question plus spécifique: j'irais avec String à moins que vous n'obteniez des avantages de performances notables en utilisant Text. Les messages d'erreur sont généralement de petites choses ponctuelles, donc l'utilisation de String ne devrait pas être un gros problème.

D'un autre côté, si vous êtes le genre de puriste idéologique qui évite le pragmatisme pour l'idéalisme, optez pour le texte.


* Je mets les erreurs de conception entre guillemets effrayants car les chaînes en tant que liste de caractères sont une propriété soignée qui les rend faciles à raisonner et à intégrer avec d'autres fonctions d'exploitation de liste existantes.

26
kqr

Si votre API vise à traiter de grandes quantités de données orientées caractères et/ou divers encodages, alors votre API doit utiliser Texte.

Si votre API est principalement destinée à traiter les petites chaînes uniques, l'utilisation du type intégré String devrait être correcte.

L'utilisation de String pour de grandes quantités de texte fera que les applications utilisant votre API consomment beaucoup plus de mémoire. Son utilisation avec des encodages étrangers pourrait sérieusement compliquer l'utilisation en fonction du fonctionnement de votre API.

La chaîne est assez chère (au moins 5N mots où N est le nombre de Char dans la chaîne). Un mot est le même nombre de bits que l'architecture du processeur (ex. 32 bits ou 64 bits): http://blog.johantibell.com/2011/06/memory-footprints-of-some-common-data .html

23
Alain O'Dea

Il y a au moins trois raisons d'utiliser [Char] dans les petits projets.

  1. [Char] ne dépend d'aucun personnel obscur, comme les pointeurs étrangers, la mémoire brute, les tableaux bruts, etc. qui peuvent fonctionner différemment sur différentes plates-formes ou même être indisponibles

  2. [Char] est la lingua franka à haskell. Il existe au moins trois méthodes "efficaces" pour gérer les données unicode dans haskell: utf8-bytestring, Data.Text.Text et Data.Vector.Unboxed.Vector Char, chacun nécessitant un traitement supplémentaire.

  3. en utilisant [Char] on accède à toute la puissance de [] monad, y compris de nombreuses fonctions spécifiques (des paquets de chaînes alternatifs essaient de l'aider, mais quand même)

Personnellement, je considère tf16 - basé sur Data.Text l'une des désignations les plus discutables de la communauté haskell, puisque tf16 combine les défauts de l'encodage tf8 et tf32 sans avoir aucun de ses avantages .

7
permeakra

Je ne pense pas qu'il y ait une seule raison technique pour que String reste. Et je peux en voir plusieurs pour que ça aille.

Dans l'ensemble, je dirais d'abord que dans le cas du texte/chaîne, il n'y a qu'une seule meilleure solution:

  • Les performances des cordes sont mauvaises, tout le monde est d'accord là-dessus

  • Le texte n'est pas difficile à utiliser. Toutes les fonctions couramment utilisées sur String sont disponibles sur Text, plus quelques-unes plus utiles dans le contexte des chaînes (substitution, remplissage, encodage)

  • avoir deux solutions crée une complexité inutile à moins que toutes les fonctions de base ne soient rendues polymorphes. Preuve: il y a SO questions sur le sujet des conversions automatiques . Donc est un problème.

Une solution est donc moins complexe que deux, et les défauts de String la feront disparaître à terme. Le plus tôt sera le mieux !

4
Titou

Je me demande si Data.Text est toujours plus efficace que Data.String ???

"contre" par exemple est O(1) pour les chaînes et O(n) pour le texte. Ajouter est O(n) pour les chaînes et O (n + m) pour les textes stricts. De même,

    let foo = "foo" ++ bigchunk
        bar = "bar" ++ bigchunk

est plus efficace en termes d'espace pour les chaînes que pour les textes stricts.

Un autre problème non lié à l'efficacité est la correspondance de modèles (code perspicuous) et la paresse (prévisible par caractère dans les chaînes, en quelque sorte l'implémentation dépend du texte paresseux).

Les textes sont évidemment bons pour les séquences de caractères statiques et pour la modification sur place. Pour d'autres formes d'édition structurelle, Data.String peut présenter des avantages.

4
Passing By