2012-06-11 20 views

Respuesta

11

La biblioteca text-show existe ahora y resuelve exactamente este problema.

Update (2016 12 de febrero)

La función show proporcionado en la biblioteca basic-prelude renders también directamente al texto:

show :: Show a => a -> Text 

basic-prelude también tiene un menor número de dependencias que text-show. Si desea utilizar basic-prelude, se ahorrará dolores de cabeza de compilación, añadiendo lo siguiente a la parte superior de su archivo de origen:

{-# LANGUAGE NoImplicitPrelude #-} 
+0

Tanto en preludio básico como en preludio con clase hay [tshow] (https://www.stackage.org/lts-8.23/hoogle?q=tshow) – mb21

2

Es trivial para escribir su propia función que lleva a cuestas fuera Show:.

showText :: Show a => a -> Text 
showText = pack . show 
+11

¿Esto tiene un impacto en el rendimiento? es decir, ¿no estoy creando una gran "Cadena" y luego la estoy convirtiendo en un "Texto", en lugar de crear el "Texto" directamente? – jameshfisher

+2

¿No pierde todas las ganancias de usar Data.Text de esta manera? Usas el texto principalmente debido a los problemas de prefromancia de 'String', y de esta forma eliminas todas las ganancias ... – Sventimir

+0

Dado que la clase de tipo' Show' básicamente solo requiere 'show :: a -> String', no hay forma para implementar 'showText' sin pasar por una cadena. Las funciones 'tshow' en preludio básico y con clase también se implementan así. – mb21

14

El problema con la creación del texto directamente es que todavía necesita saber el tamaño total de la estricta bloque de texto antes de llenarlo en Puede hacerlo mejor con un esquema de Constructor y usando Data.Text.Lazy. Dan Doel lo hace en bytestring-show, pero no conozco un equivalente para Text.

+0

Hablando de leer/mostrar funciones ...¿Puede un par de ("función de lectura que puede fallar", "función de mostrar") para un tipo de datos dado convertirse en un prisma desde Control.Lens? – danidiaz

+0

¡Sip! Necesita la capacidad de ejecutar el 'Lectura' y salir si coincide o no, lo cual fue agregado recientemente a la base. –

5

Para el caso particular de Int valores, aquí está el código para convertirlos en Text estrictos valores sin utilizar Strings en una etapa intermedia:

import Data.Text 
import Data.Text.Lazy (toStrict) 
import Data.Text.Lazy.Builder (toLazyText) 
import Data.Text.Lazy.Builder.Int (decimal) 

showIntegral :: Integral a => a -> T.Text 
showIntegral = toStrict. toLazyText . decimal 

Módulo Data.Text.Lazy.Builder.RealFloat ofrece una funcionalidad similar para valores de coma flotante.

Con estos podemos definir una versión propia de la clase de tipos Show:

import Data.Text 
import Data.Text.Lazy (toStrict) 
import Data.Text.Lazy.Builder (toLazyText) 
import Data.Text.Lazy.Builder.Int (decimal) 
import Data.Text.Lazy.Builder.RealFloat (realFloat) 

class ShowText a where 
    showText :: a -> Text 

instance ShowText Int where 
    showText = toStrict . toLazyText . decimal 

instance ShowText Float where 
    showText = toStrict . toLazyText . realFloat 

entonces podemos empezar a añadir más instancias (una para tuplas sería útil, por ejemplo).

Cuestiones relacionadas