string haskell type-conversion

Conversión automática entre String y Data.Text en haskell



type-conversion (2)

No.

Haskell no tiene coerciones implícitas por razones técnicas, filosóficas y casi religiosas.

Como comentario, la conversión entre estas representaciones no es gratuita y a la mayoría de las personas no les gusta la idea de que tiene ocultos y los cómputos potencialmente costosos merodean por ahí. Además, con las cadenas en forma de listas perezosas, es posible que la conversión a un valor de Text no termine.

Podemos convertir los literales a Text s automáticamente con OverloadedString s deslizando una cadena literal "foo" a fromString "foo" y fromString for Text solo llama al pack .

La pregunta podría ser preguntarse por qué estás coaccionando tanto. ¿Hay algún por qué necesitas unpack valores de Text tan a menudo? Si los cambias constantemente a cadenas, se pierde un poco el propósito.

Como Nikita Volkov mencionó en su pregunta Data.Text vs String , también me pregunté por qué tengo que lidiar con las diferentes implementaciones de type String = [Char] y Data.Text en Data.Text . En mi código utilizo las funciones de pack y unpack muy a menudo.

Mi pregunta: ¿Hay una manera de tener una conversión automática entre ambos tipos de cadenas para que pueda evitar escribir pack y unpack tan a menudo?

En otros lenguajes de programación como Python o JavaScript hay, por ejemplo, una conversión automática entre enteros y flotadores si es necesario. ¿Puedo alcanzar algo como esto también en haskell? Sé que los lenguajes mencionados están mal escritos, pero escuché que C ++ tiene una característica similar.

Nota: Ya conozco la extensión de idioma {-# LANGUAGE OverloadedStrings #-} . Pero como entiendo, las extensiones de este lenguaje solo se aplican a las cadenas definidas como "..." . Quiero tener una conversión automática para las cadenas que obtuve de otras funciones o tengo argumentos en las definiciones de funciones.

Pregunta extendida: Haskell. Text o Bytestring cubre también la diferencia entre Data.Text y Data.ByteString . ¿Hay una manera de tener una conversión automática entre las tres cadenas String , Data.Text y Data.ByteString ?


Casi sí: Data.String.Conversions

Las bibliotecas de Haskell utilizan diferentes tipos, por lo que hay muchas situaciones en las que no hay más remedio que usar la conversión en gran medida, por desagradable que sea, reescribir bibliotecas no cuenta como una opción real.

Veo dos problemas concretos, cualquiera de los cuales es potencialmente un problema importante para la adopción de Haskell:

  • la codificación termina requiriendo conocimientos específicos de implementación de las bibliotecas que desea utilizar. Este es un gran problema para un lenguaje de alto nivel

  • el desempeño en tareas simples es malo, lo cual es un gran problema para un lenguaje generalista .

Resumen de los tipos específicos

En mi experiencia, el primer problema es el tiempo dedicado a adivinar el nombre del paquete que contiene la función correcta para la instalación de tuberías entre bibliotecas que operan básicamente con los mismos datos.

Para ese problema hay una solución realmente útil: el package Data.String.Conversions , siempre que se sienta cómodo con UTF-8 como su codificación predeterminada.

Este paquete proporciona una única función de conversión cs entre varios tipos diferentes.

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

Así que solo import Data.String.Conversions , y usa cs que import Data.String.Conversions la versión correcta de la función de conversión de acuerdo con los tipos de entrada y salida.

Ejemplo:

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: en GHCi, por lo general, no tiene un contexto que proporcione el tipo de destino, por lo que dirige la conversión indicando explícitamente el tipo del resultado, como para read

let z = cs x :: ByteString

El rendimiento y el clamor por una solución "verdadera"

Todavía no conozco ninguna solución verdadera, pero ya podemos adivinar la dirección

  • es legítimo requerir conversión porque los datos no cambian;
  • el mejor rendimiento se logra al no convertir los datos de un tipo a otro para fines administrativos;
  • La coerción es malvada, incluso coercitiva.

Por lo tanto, la dirección debe ser hacer que estos tipos no sean diferentes, es decir, reconciliarlos bajo (o sobre) un arquetipo del cual se derivarían todos, permitiendo la composición de funciones utilizando diferentes derivaciones, sin la necesidad de convertir.

Nota: No puedo evaluar la viabilidad / los posibles inconvenientes de esta idea. Puede haber algunos tapones muy buenos.