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.