2010-07-12 7 views
20

하스켈에서 String을 ByteString으로 변환하는 가장 좋은 방법은 무엇입니까? 이 문제에String을 ByteString으로 변환하는 가장 좋은 방법은 무엇입니까

내 직감 반응은

import qualified Data.ByteString as B 
import Data.Char (ord) 

packStr = B.pack . map (fromIntegral . ord) 

입니다하지만이 만족하지 않는 것 같습니다.

+4

현대 : 일반적으로'[Char]'를'Text'로,'[Word8]'을'ByteString'으로 변환해야합니다. 그것의 여전히'팩') : – alternative

+2

유니 코드를 바이트로 변환하는 것은 유니 코드 인코딩을 사용하는 것을 포함합니다. 'pack'을 사용하는 것은 안전하지 않은 캐스팅과 더 유사합니다. – tibbe

답변

24

Data.ByteString[.Lazy].Char8.pack

당신은 일반적으로 기능을 찾을 hoogle를 사용할 수 있습니다.

+0

Google을 사용하는 좋은 방법입니다! – eccstartup

+0

이것은 Char8 ByteStrings에서 작동하지만 Word8의 ByteString에는 무엇을 사용할 수 있습니까? –

+1

@fractal 그들은 똑같은 유형이므로 둘 다 작동합니다. –

14

Data.ByteString.UTF8.fromString도 유용합니다. Char8 버전은 유니 코드를 잃고 UTF8은 UTF8로 인코딩 된 ByteString을 만듭니다. 둘 중 하나를 선택해야합니다. Data.ByteString.Char8.pack 효과적으로 문제의 버전과 동일하며, 무엇을 수 없을 수도 있습니다 : 다른 답변에 대해서는

import qualified Data.ByteString as B 
import qualified Data.Text as T 
import Data.Text.Encoding (encodeUtf8) 

packStr'' :: String -> B.ByteString 
packStr'' = encodeUtf8 . T.pack 

:

+0

질문이 올 경우 :이 기능은 GHC와 함께 제공되는 일련의 라이브러리 만 색인하기 때문에 Hoogle에서 찾아 볼 수 없습니다. Hoogle에서 색인을 생성 한 라이브러리 집합을 확장하는 것은 여러 번 나 왔지만 Hoogle 개발자 (Neil)의 시간 제약으로 인해 생각하지 못했습니다. 참고로 여기에서 설명하는 함수는 utf8-string 패키지에 있습니다. –

+0

@TomMD : Hayoo가이 문제를 해결합니다. http://holumbus.fh-wedel.de/hayoo/hayoo.html#0:String%20-%3E%20ByteString – Peaker

+0

@peaker : 만족하지 않습니다. Hayoo는 유형 검색시 유형이 좋지 않은 경우 특히 유형이 일반 또는 다형성 인 경우 특히 그렇습니다. –

5

안전한 방법은 유니 코드 문자열을 인코딩 포함 할 것이다 당신이 원하는 :

import qualified Data.ByteString as B 
import qualified Data.ByteString.Char8 as C 
import qualified Data.Text as T 
import Data.Text.Encoding (encodeUtf8) 
import Data.Char (ord) 

packStr, packStr', packStr'' :: String -> B.ByteString 
packStr = B.pack . map (fromIntegral . ord) 
packStr' = C.pack 
packStr'' = encodeUtf8 . T.pack 

*Main> packStr "hellö♥" 
"hell\246e" 
*Main> packStr' "hellö♥" 
"hell\246e" 
*Main> packStr'' "hellö♥" 
"hell\195\182\226\153\165" 

Data.ByteString.UTF8.fromString은 괜찮지 만 Data.Text.Encoding는 하스켈 플랫폼과 함께 제공하면서 UTF8 문자열 패키지가 필요합니다.

+1

'Codec.Binary.UTF8.String'도 사용할 수 있습니다. –

4

Haskell String/Text/ByteString strict/lazy 변환에 대한 제 치트 시트는 원하는 인코딩이 UTF-8이라고 가정합니다. Data.Text.Encoding 라이브러리에는 다른 인코딩을 사용할 수 있습니다.

lazyByteString :: BL.ByteString 
lazyByteString = "lazyByteString ä ß" -- BAD! 

이 예기치 않은 방식으로 인코딩 얻을 것이다 :

확신에 하지 쓰기 (OverloadedStrings 사용)을 확인하시기 바랍니다. 시도해보십시오

lazyByteString = BLU.fromString "lazyByteString ä ß" -- good 

대신에보십시오.

'Text'유형의 문자열 리터럴은 인코딩과 관련하여 문제가 없습니다.

치트 시트 :

import Data.ByteString.Lazy as BL 
import Data.ByteString as BS 
import Data.Text as TS 
import Data.Text.Lazy as TL 
import Data.ByteString.Lazy.UTF8 as BLU 
import Data.ByteString.UTF8 as BSU 
import Data.Text.Encoding as TSE 
import Data.Text.Lazy.Encoding as TLE 

-- String <-> ByteString 

BLU.toString :: BL.ByteString -> String 
BLU.fromString :: String -> BL.ByteString 
BSU.toString :: BS.ByteString -> String 
BSU.fromString :: String -> BS.ByteString 

-- String <-> Text 

TL.unpack :: TL.Text -> String 
TL.pack :: String -> TL.Text 
TS.unpack :: TS.Text -> String 
TS.pack :: String -> TS.Text 

-- ByteString <-> Text 

TLE.encodeUtf8 :: TL.Text -> BL.ByteString 
TLE.decodeUtf8 :: BL.ByteString -> TL.Text 
TSE.encodeUtf8 :: TS.Text -> BS.ByteString 
TSE.decodeUtf8 :: BS.ByteString -> TS.Text 

-- Lazy <-> Strict 

BL.fromStrict :: BS.ByteString -> BL.ByteString 
BL.toStrict :: BL.ByteString -> BS.ByteString 
TL.fromStrict :: TS.Text -> TL.Text 
TL.toStrict :: TL.Text -> TS.Text 

하시기 바랍니다 +1 Peaker의 대답, 그는 제대로 인코딩을 다루고 있기 때문이다.

관련 문제