텍스트 또는 바이트 문자열


78

좋은 날.

내가 지금 Haskell에 대해 싫어하는 것은 문자열 작업을위한 패키지의 양입니다.

처음에는 네이티브 Haskell [Char]문자열을 사용했지만 해킹 라이브러리를 사용하려고했을 때 끝없는 변환으로 완전히 잃었습니다. 모든 패키지는 다른 문자열 구현을 사용하는 것처럼 보이며 일부는 자체 수작업을 채택합니다.

다음으로 Data.Text문자열과 OverloadedStrings확장자로 코드를 다시 작성 했습니다 Text. 더 넓은 함수 세트를 가지고 있기 때문에 선택 했지만 많은 프로젝트에서 ByteString.
누군가가 왜 하나 또는 다른 것을 사용 해야하는지 짧은 추론을 줄 수 있습니까?

PS : BTW 어떻게 변환하는 방법 TextByteString?

예상 유형 Data.ByteString.Lazy.Internal.ByteString 을 유추 된 유형 텍스트 와 일치시킬 수 없습니다. 예상 유형 : IO Data.ByteString.Lazy.Internal.ByteString 유추 된 유형 : IO 텍스트

encodeUtf8에서 시도 Data.Text.Encoding했지만 운이 없습니다.

유추 된 유형 Data.ByteString.Internal.ByteString 에 대해 예상 유형 Data.ByteString.Lazy.Internal.ByteString 을 일치시킬 수 없습니다.

UPD :

* Chunks goodness가 갈 길처럼 보이지만 결과에 다소 충격을 받았으며 원래 기능은 다음과 같습니다.

htmlToItems :: Text -> [Item]
htmlToItems =
    getItems . parseTags . convertFuzzy Discard "CP1251" "UTF8"

그리고 이제 :

htmlToItems :: Text -> [Item]
htmlToItems =
    getItems . parseTags . fromLazyBS . convertFuzzy Discard "CP1251" "UTF8" . toLazyBS
    where
      toLazyBS t = fromChunks [encodeUtf8 t]
      fromLazyBS t = decodeUtf8 $ intercalate "" $ toChunks t

그리고 예,이 기능은 작동하지 않습니다. 왜냐하면 우리 Text가 그것을 제공한다면 이 텍스트가 적절하게 인코딩되고 사용할 준비가되어 있고 변환하는 것은 어리석은 일이라고 확신합니다. 그러나 그런 장황한 변환은 여전히 외부 어딘가에 두십시오 htmltoItems.


41
Haskell 여러분은 통일 된 문자열을
Ankur

8
@Ankur : Text사실상 텍스트 구현이되고 있습니다. 문자열은 여전히 ​​레거시 이유와 단순한 이유로 주위에 있지만 심각한 텍스트 조작을 위해서는 Text를 사용해야합니다.
ivanm

2
@ivanm : 레거시 바이트 문자열 기반 라이브러리가 모두 변환을 이동한다면!
John L

1
@ivanm 실제로 Text를 사용할 수없고, 이제 라이브러리 (Database.MongoDB, Text.Iconv)를 거의 사용하지 않고 존경하는 사람이 없으며 Text모든 변환을 수동으로 수행하는 것은 제정신이 아닙니다.
Dfr

2
원래 텍스트는 어떻게 그리고 어디서 얻습니까? 문제가 발생하는 이유는 다른 인코딩간에 텍스트를 변환 할 필요가 없기 때문입니다. 처음부터 올바른 인코딩으로 텍스트 데이터를 디코딩 한 다음 다음을 사용해야합니다.htmlToItems = getItems . parseTags
shang

답변:


68

ByteStrings주로 바이너리 데이터에 유용하지만 ASCII 문자 집합 만 있으면 텍스트를 처리하는 효율적인 방법이기도합니다. 유니 코드 문자열을 처리해야하는 경우 Text. 그러나 둘 다 다른 것을 대체하는 것이 아니며 일반적으로 다른 용도로 사용된다는 점을 강조해야합니다. Text순수한 유니 코드 를 나타내지 만 ByteString소켓이나 파일을 통해 텍스트를 전송할 때마다 이진 표현 으로 /부터 인코딩해야 합니다. .

다음은 유니 코드 코드 포인트 ( Text)와 인코딩 된 바이너리 바이트 ( ByteString) 의 관계를 설명하는 적절한 작업을 수행하는 유니 코드의 기본에 대한 좋은 기사입니다 . 모든 소프트웨어 개발자는 절대적으로 유니 코드와 문자에 대해 알아야합니다. 세트

Data.Text.Encoding 모듈을 사용하여 두 데이터 유형간에 변환하거나 지연 변형을 사용하는 경우 Data.Text.Lazy.Encoding 을 사용할 수 있습니다 (오류 메시지를 기반으로하는 것처럼 보임 ).


내 모든 문자열이 이미 Strict : 예상 유형과 일치 할 수 없기 때문에 반대편에 부딪 혔습니다. Text against inferred type Data.Text.Lazy.Internal.Text그래서 fromChunks for Text를 찾았지만 최종 결과는 아직 못 생겼습니다.
Dfr

5
ASCII 만 필요한 경우에도 "텍스트"데이터에 바이트 문자열을 사용하지 마십시오. 텍스트 데이터에는 Text를 사용하고 패킹 된 데이터 구조에는 ByteString을 사용합니다. 의미 론적으로 표현해야하는 유형에 대해 모두 동의하면 어떤 유형 을 사용할 지에 대한 혼동이 줄어들고 궁극적으로 유형 간의 변환이 줄어 듭니다.
nomen

1
"예를 들어 소켓이나 파일을 통해 텍스트를 전송할 때마다 이진 ByteString 표현으로 /부터 인코딩해야합니다." text패키지는 실제로 이미 파일을 사용하여 작업 할 수있는 기능을 제공합니다.

1
예, Data.Text.IO모듈에는 파일 작업을위한 기능이 있지만 원하는 것이 거의 없습니다. 시스템 로케일의 기본 문자 세트 TextByteString사용하여 내부적으로 디코딩 합니다. 파일에 다른 인코딩이있는 경우 런타임 오류 또는 가비지 텍스트가 발생합니다. 명시 적으로 인코딩 및 디코딩을 수행하는 것이 거의 항상 올바른 옵션입니다.
shang

26

텍스트 데이터에 Data.Text를 사용하고 싶을 것입니다.

encodeUtf8갈 길입니다. 이 오류 :

유추 된 유형 Data.ByteString.Internal.ByteString에 대해 예상 유형 Data.ByteString.Lazy.Internal.ByteString을 일치시킬 수 없습니다.

게으른 바이트 문자열 을 예상하는 코드에 엄격한 바이트 문자열을 제공하고 있음을 의미합니다 . 다음 기능으로 변환이 쉽습니다 .fromChunks

Data.ByteString.Lazy.fromChunks :: [Data.ByteString.Internal.ByteString] -> ByteString

그래서 당신이해야 할 일은 함수를 추가하는 것입니다 fromChunks [myStrictByteString] 게으른 바이트 문자열이 예상되는 곳에 입니다.

이중 기능으로 다른 방식으로 변환 할 수 있습니다. toChunks 지연 바이트 문자열을 취하고 엄격한 청크 목록을 제공하는 .

일부 패키지의 관리자에게 바이트 문자열 인터페이스 대신 또는 추가로 텍스트 인터페이스를 제공 할 수 있는지 물어볼 수 있습니다.


5

하나의 기능을 사용 cs로부터를Data.String.Conversions .

입력 및 예상 유형에 따라 String, ByteStringText( ByteString.Lazy및 및 Text.Lazy) 간에 변환 할 수 있습니다.

여전히 호출해야하지만 더 이상 각 유형에 대해 걱정할 필요가 없습니다.

사용 예는 이 답변 을 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.