Лучший способ конвертировать между [Char] и [Word8]? - PullRequest
10 голосов
/ 16 января 2011

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

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

Вики-страница Haskell Prime по типам символов , кажется, указывает, что это что-то еще разрабатывается на языке Haskell / Prelude.

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

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

Спасибо!

Ответы [ 6 ]

4 голосов
/ 16 января 2011

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

Для Char и Strings вы можете избежать использования Data.ByteString.Char8.pack / unpack или некоторой комбинации map, 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

3 голосов
/ 09 февраля 2014

Вот что у меня есть, без использования внутренних функций 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 в символ. Составив их все вместе, мы получим желаемую функцию!

2 голосов
/ 16 января 2011

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

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

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

1 голос
/ 10 февраля 2014

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

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

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

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

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

0 голосов
/ 29 августа 2017

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

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

toWord8 :: Char -> Word8
toWord8 = unsafeCoerce

strToWord8 :: String -> Word8
strToWord8 = map toWord8
0 голосов
/ 12 марта 2013

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

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

strToWord8s :: String -> [Word8]
strToWord8s = unpackBytes . pack 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...