Лучший способ конвертировать между [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