2011-01-15 3 views
10

Я новичок в Haskell, и я пытаюсь использовать чистую реализацию SHA1 в своем приложении (Data.Digest.Pure.SHA) с библиотекой JSON (AttoJSON).Лучший способ конвертировать между [Char] и [Word8]?

AttoJSON использует Data.ByteString.Char8 bytestrings, SHA использует Data.ByteString.Lazy bytestrings, а некоторые из моих строковых литералов в моем приложении: [Char].

Haskell Prime's wiki page on Char types, кажется, указывает, что это что-то еще разрабатывается на языке Haskell/Prelude.

И this blogpost on unicode support перечисляет несколько библиотек, но его пару лет.

Каков наилучший способ преобразования между этими типами и некоторые из компромиссов?

Спасибо!

+0

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

+0

Обратите внимание, что 'Char' * нельзя * безопасно преобразовать в' Word8' потому что 'Char' может хранить гораздо больше значений, чем 'Word8'. – singpolyma

ответ

2

Char8 и normal bytestrings - это то же самое, только с разными интерфейсами в зависимости от того, какой модуль вы импортируете. В основном вы хотите конвертировать между строгими и ленивыми байтами, для которых вы используете toChunks и fromChunks.

Чтобы разместить символы в байтах, используйте pack.

Также обратите внимание, что если ваши символы содержат кодовые обозначения, которые представляют собой многобайтовые представления в UTF-8, тогда будут проблемы.

4

Для преобразования между Char8 и Word8 вы должны использовать преобразования toEnum/fromEnum, поскольку они представляют одни и те же данные.

Для Char и Strings вы можете уйти с Data.ByteString.Char8.pack/unpack или какую-то комбинацию карт, toEnum и fromEnum, но это выбрасывает данные, если вы используете что-либо другое, кроме ASCII.

Для строк, которые могут содержать больше, чем просто ASCII, популярным выбором является кодировка UTF8. Мне нравится пакет utf8-строки для этого:

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

0

Может быть, вы хотите сделать это:

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

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

Вот что у меня есть, без использования внутренних функций байтовой строки в.

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 на байтовой строки дает нам [Word8], мы применяем (chr . fromEnum), который преобразует любой тип Enum к символу. Составляя их вместе, мы будем выполнять функцию, которую хотим!

1

Примечание: Это отвечает на вопрос в очень конкретном случае (вызывающие функции на жестко закодированных строках).

Это может показаться незначительной проблемой, поскольку функции преобразования существуют, как описано в предыдущих ответах. Но мне нужен метод для сокращения административного кода, то есть кода, который вы должны написать, чтобы просто работать с функциями.

Решение для сокращения типа кода обработки строк является использование OverloadedStrings прагму и импортировать соответствующий модуль (ы)

{-# 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" 

Примечание: тип myWordList выводится компилятором.

  • Если вы не используете его в bslHandling, то выше заявление будет yeld классическим [Char] типа.

  • Это не решает проблему перехода от одного конкретного типа к другим

Надеется, что это помогает

0

Предполагая, что Char и Word8 такой же,

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

toWord8 :: Char -> Word8 
toWord8 = unsafeCoerce 

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

Это очень плохое предположение, учитывая поддержку Haskell для Unicode. unsafeCoerce называется небезопасным именно из-за таких вещей. – Evi1M4chine

+0

Действительно, ответ Джейкоба Ван намного лучше. – penkovsky

Смежные вопросы