2011-01-15 11 views
10

Sono nuovo di Haskell e sto cercando di utilizzare un'implementazione pura SHA1 nella mia app (Data.Digest.Pure.SHA) con una libreria JSON (AttoJSON).Il modo migliore per convertire tra [Char] e [Word8]?

AttoJSON utilizza i bytestrings Data.ByteString.Char8, SHA utilizza gli estensori Data.ByteString.Lazy e alcuni dei miei valori letterali di stringa nella mia app sono [Char].

Haskell Prime's wiki page on Char types sembra indicare che questo è qualcosa che viene ancora elaborato nella lingua Haskell/Preludio.

E this blogpost on unicode support elenca alcune librerie ma ha un paio di anni.

Qual è il miglior modo per convertire tra questi tipi e quali sono alcuni dei compromessi?

Grazie!

+0

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

+0

Si noti che un 'Char' * non può * essere tranquillamente convertito in' Word8' perché 'Char' può memorizzare molti più valori di 'Word8'. – singpolyma

risposta

2

Char8 e normali bytestring sono la stessa cosa, solo con interfacce diverse a seconda del modulo che si importa. Principalmente si desidera effettuare la conversione tra i perlopiù stretti e pigri, per i quali si utilizza toChunks e fromChunks.

Per inserire caratteri in byte, utilizzare pack.

Si noti inoltre che se i caratteri includono codepoints quali rappresentazioni multibyte in UTF-8, allora ci saranno problemi.

4

Per la conversione tra Char8 e Word8 dovresti essere in grado di utilizzare le conversioni toEnum/fromEnum, in quanto rappresentano gli stessi dati.

Per Char e stringhe potresti essere in grado di scappare con Data.ByteString.Char8.pack/unpack o una sorta di combinazione di mappe, toEnum e fromEnum, ma che genera dati se stai utilizzando qualcosa di diverso da ASCII.

Per stringhe che potrebbero contenere più di un semplice ASCII, la scelta più comune è la codifica UTF8. Mi piace il pacchetto utf8-stringa per questo:

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

0

forse si vuole fare questo:

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

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

Ecco quello che ho, senza l'utilizzo di funzioni interne di ByteString.

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 su un ByteString ci dà [Word8], applichiamo (chr . fromEnum) che converte qualsiasi tipo Enum ad un personaggio. Compilandoli tutti insieme faremo la funzione che vogliamo!

1

Nota: questo risponde alla domanda in un caso molto specifico (chiamata funzioni su stringhe hardcoded).

Questo può sembrare un problema secondario perché le funzioni di conversione esistono come descritto nelle risposte precedenti. Ma volevo un metodo per ridurre il codice amministrativo, cioè il codice che devi scrivere solo per far funzionare le funzioni insieme.

La soluzione per ridurre codice tipo di gestione per le stringhe è quello di utilizzare il OverloadedStrings pragma e importare il relativo modulo (s)

{-# 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 myWordList viene dedotto dal compilatore.

  • Se non si utilizza in bslHandling, poi la dichiarazione di cui sopra sarà resa una classica [Char] tipo.

  • Non risolve il problema di passare da un tipo specifico ad un altro

Speranza che aiuta

0

Supponendo che Char e Word8 sono gli stessi,

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

toWord8 :: Char -> Word8 
toWord8 = unsafeCoerce 

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

Questa è una pessima ipotesi, dato il supporto di Haskell per Unicode. unsafeCoerce viene chiamato non sicuro esattamente a causa di cose come questa. – Evi1M4chine

+0

In effetti, la risposta di Jacob Wang è molto meglio. – penkovsky

Problemi correlati