2011-01-15 22 views
10

Soy nuevo en Haskell y estoy tratando de usar una implementación pura de SHA1 en mi aplicación (Data.Digest.Pure.SHA) con una biblioteca JSON (AttoJSON).¿La mejor manera de convertir entre [Char] y [Word8]?

AttoJSON utiliza Data.ByteString.Char8 cadenas de bytes, SHA usa Data.ByteString.Lazy bytes, y algunos de mis literales de cadena en mi aplicación son [Char].

Haskell Prime's wiki page on Char types parece indicar que esto todavía se está resolviendo en el lenguaje Haskell/Preludio.

Y this blogpost on unicode support enumera algunas bibliotecas pero tiene un par de años.

¿Cuál es la mejor forma actual de conversión entre estos tipos, y cuáles son algunas de las ventajas y desventajas?

Gracias!

+0

http: //hackage.haskell.org/packages/archive/utf8-string/0.3.7/doc/html/Data-ByteString-Lazy-UTF8.html – singpolyma

+0

Tenga en cuenta que un 'Char' * no puede * convertirse con seguridad en' Word8' porque 'Char' puede almacenar muchos más valores que 'Word8'. – singpolyma

Respuesta

2

Las cadenas de bytes Char8 y normal son lo mismo, solo que con diferentes interfaces según el módulo que importe. Principalmente quiere convertir cadenas de bytes estrictas y perezosas, para las cuales usa toChunks y fromChunks.

Para poner caracteres en cadenas de bytes, use pack.

También tenga en cuenta que si sus caracteres incluyen puntos de código que representan múltiples bytes en UTF-8, entonces habrá problemas.

4

Para la conversión entre Char8 y Word8 debe poder utilizar las conversiones de EnEntrar/desdeEntrado, ya que representan los mismos datos.

Para Char y cadenas, es posible que pueda salirse con Data.ByteString.Char8.pack/unpack o algún tipo de combinación de mapa, toEnum y fromEnum, pero que arroja datos si está utilizando algo que no sea ASCII.

Para las cadenas que podrían contener algo más que ASCII, una opción popular es la codificación UTF8. Me gusta el paquete utf8-cadena para esto:

http://hackage.haskell.org/packages/archive/utf8-string/0.3.6/doc/html/Codec-Binary-UTF8-String.html

0

Tal vez usted quiere hacer esto:

import Data.ByteString.Internal (unpackBytes) 
import Data.ByteString.Char8 (pack) 
import GHC.Word (Word8) 

strToWord8s :: String -> [Word8] 
strToWord8s = unpackBytes . pack 
3

Esto es lo que tengo, sin necesidad de utilizar las funciones internas de cadena de bytes.

import Data.ByteString as S (ByteString, unpack) 
import Data.ByteString.Char8 as C8 (pack) 
import Data.Char (chr) 

strToBS :: String -> S.ByteString 
strToBS = C8.pack 

bsToStr :: S.ByteString -> String 
bsToStr = map (chr . fromEnum) . S.unpack 

S.unpack en un ByteString nos da [Word8], aplicamos (chr . fromEnum) que convierte cualquier tipo de enumeración a un personaje. ¡Al componer todos juntos, conseguiremos la función que queremos!

1

Nota: Esto responde a la pregunta en un caso muy específico (llamando a funciones en cadenas codificadas).

Esto puede parecer un problema menor porque las funciones de conversión existen como se detalla en las respuestas anteriores. Pero quería un método para reducir el código administrativo, es decir, el código que tiene que escribir solo para que las funciones funcionen juntas.

La solución para reducir el código de tipo de manipulación de cadenas es usar el pragma OverloadedStrings e importar el módulo (s) relevante

{-# LANGUAGE OverloadedStrings #-} 
module Dummy where 
import Data.ByteString.Lazy.Char8 (ByteString, append) 

bslHandling :: ByteString -> ByteString 
bslHandling = (append myWord8List) 

myWord8List = "I look like a String, but I'm actually a ByteString" 

Nota: Tipo de myWordList se infiere por el compilador.

  • Si no lo utiliza en bslHandling, a continuación, la declaración anterior se yeld una clásica [Char] tipo.

  • No resuelve el problema de pasar de un tipo específico a otro

Espero que ayuda

0

Suponiendo que Char y Word8 son los mismos,

import Data.Word (Word8) 
import Unsafe.Coerce (unsafeCoerce) 

toWord8 :: Char -> Word8 
toWord8 = unsafeCoerce 

strToWord8 :: String -> Word8 
strToWord8 = map toWord8 
+0

Esa es una suposición muy mala, dado el soporte de Haskell para Unicode. insafeCero se llama inseguro exactamente por cosas como esta. – Evi1M4chine

+0

De hecho, la respuesta de Jacob Wang es mucho mejor. – penkovsky

Cuestiones relacionadas