Лучший способ конвертировать между [Char] и [Word8]?

Я новичок в Haskell, и я пытаюсь использовать чистую реализацию SHA1 в своем приложении (Data.Digest.Pure.SHA) с помощью библиотеки JSON (AttoJSON).

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

Haskell Prime wiki на страницах Char, кажется, указывает, что это что-то еще разрабатывается на языке Haskell/Prelude.

И этот блогпост в поддержке юникода содержит несколько библиотек, но его пару лет.

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

Спасибо!

Ответ 1

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

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

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

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

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

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

Решение по сокращению кода обработки строк для строк - использовать прагму 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, то указанное выше объявление приведет к классическому типу [Char].

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

Надеюсь, что это поможет

Ответ 5

Возможно, вы хотите сделать это:

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

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

Ответ 6

Предполагая, что Char и Word8 одинаковы,

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

toWord8 :: Char -> Word8
toWord8 = unsafeCoerce

strToWord8 :: String -> Word8
strToWord8 = map toWord8