在[Char]和[Word8]之间进行转换的最佳方式是什么?

时间:2011-01-15 21:47:10

标签: string unicode haskell utf-8

我是Haskell的新手,我正在尝试在我的应用程序(Data.Digest.Pure.SHA)中使用带有JSON库(AttoJSON)的纯SHA1实现。

AttoJSON使用Data.ByteString.Char8个字符串,SHA使用Data.ByteString.Lazy个字符串,我的应用中的一些字符串文字是[Char]

Haskell Prime's wiki page on Char types似乎表明这仍然是在Haskell语言/ Prelude中解决的问题。

this blogpost on unicode support列出了一些图书馆,但已有几年了。

目前在这些类型之间进行转换的最佳方法是什么,以及有哪些权衡?

谢谢!

6 个答案:

答案 0 :(得分:4)

对于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

答案 1 :(得分:3)

这就是我所拥有的,而不使用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
ByteString上的

S.unpack给我们[Word8],我们应用(chr . fromEnum)将任何枚举类型转换为字符。通过将所有这些组合在一起,我们将获得我们想要的功能!

答案 2 :(得分:2)

Char8和普通的字节串是一样的,只是根据你导入的模块使用不同的接口。主要是要在严格和懒惰的字节串之间进行转换,使用toChunksfromChunks

要将字符串放入字节串,请使用pack

另请注意,如果您的字符包含UTF-8中多字节表示的代码点,则会出现问题。

答案 3 :(得分: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中使用它,那么上面的声明将会产生一个经典的[Char]类型。

  • 它没有解决从一种特定类型传递到另一种特定类型的问题

希望有所帮助

答案 4 :(得分:0)

也许你想这样做:

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

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

答案 5 :(得分:0)

假设Char和Word8相同,

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

toWord8 :: Char -> Word8
toWord8 = unsafeCoerce

strToWord8 :: String -> Word8
strToWord8 = map toWord8