2011-01-15 2 views
10

Je suis nouveau à Haskell et j'essaie d'utiliser une implémentation SHA1 pure dans mon application (Data.Digest.Pure.SHA) avec une bibliothèque JSON (AttoJSON). AttoJSON utilise Data.ByteString.Char8 bytestrings, SHA utilise Data.ByteString.Lazy bytestrings et certains de mes littéraux de chaîne dans mon application sont [Char].La meilleure façon de convertir entre [Char] et [Word8]?

Haskell Prime's wiki page on Char types semble indiquer que c'est quelque chose qui est en train d'être élaboré dans le langage Haskell/Prelude.

Et this blogpost on unicode support répertorie quelques bibliothèques, mais il a quelques années.

Quelle est la meilleure façon actuelle de convertir entre ces types, et quels sont les compromis?

Merci!

+0

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

+0

Notez qu'un 'Char' * ne peut pas * être converti en toute sécurité en' Word8' parce que 'Char' peut stocker beaucoup plus de valeurs que «Word8». – singpolyma

Répondre

2

Char8 et bytestrings normales sont la même chose, juste avec des interfaces différentes selon le module que vous importez. Principalement, vous voulez convertir entre strict et paresseux bytestrings, pour lequel vous utilisez toChunks et fromChunks.

Pour placer des caractères dans des chaînes d'octets, utilisez pack.

Notez également que si vos caractères incluent des points de code avec des représentations multi-octets en UTF-8, il y aura des problèmes.

4

Pour la conversion entre Char8 et Word8, vous devriez pouvoir utiliser les conversions toEnum/fromEnum, car elles représentent les mêmes données. Pour Char et Strings, vous pourriez être en mesure de sortir avec Data.ByteString.Char8.pack/unpack ou une sorte de combinaison de map, toEnum et fromEnum, mais qui jette des données si vous utilisez autre chose que ASCII.

Pour les chaînes qui peuvent contenir plus que du code ASCII, le codage UTF8 est un choix populaire. J'aime le paquet utf8-string pour cela:

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

0

Peut-être que vous voulez faire ceci:

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

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

Voici ce que j'ai, sans utiliser les fonctions internes de 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 sur un ByteString nous donne [Word8], nous appliquons (chr . fromEnum) qui convertit tout type Enum à un personnage. En les composant tous ensemble, nous aurons la fonction que nous voulons!

1

Remarque: Ceci répond à la question dans un cas très spécifique (appel de fonctions sur des chaînes codées en dur).

Cela peut sembler un problème mineur car les fonctions de conversion existent comme indiqué dans les réponses précédentes. Mais je voulais une méthode pour réduire le code administratif, c'est-à-dire le code que vous devez écrire juste pour que les fonctions fonctionnent ensemble.

La solution pour réduire le code de type de traitement pour les chaînes est d'utiliser la OverloadedStrings pragma et importer le module concerné (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" 

Note: type myWordList est déduit par le compilateur.

  • Si vous ne l'utilisez pas dans bslHandling, la déclaration ci-dessus va Yeld un type [Char] classique.

  • Il ne résout pas le problème de passer d'un type spécifique à un autre

it helps

0

Si l'on suppose que Char et Word8 sont les mêmes,

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

toWord8 :: Char -> Word8 
toWord8 = unsafeCoerce 

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

C'est une très mauvaise hypothèse, étant donné le support de Haskell pour Unicode. unsafeCoerce est considéré comme dangereux à cause de choses comme ça. – Evi1M4chine

+0

En effet, la réponse de Jacob Wang est beaucoup mieux. – penkovsky

Questions connexes