2012-12-29 1 views
18

내 응용 프로그램에서 작업 Aeson not decoding UTF8 input의 문제가 발생했습니다. 깊은 파고 들자면 Attoparsec의 Parser ByteString에 의존한다는 것을 알았습니다.이 문제는 저에게 문제의 근원 인 것 같습니다. 그러나 실제로 제가 여기서 요구하는 것이 아닙니다.왜 라이브러리 디자이너가 Text가 적합한 것으로 보이는 ByteString을 사용합니까?

내가보기에 사람들이 보았던 유일한 장소가 아니란 점은 나에게 명백한 것처럼, Text 만 적합합니다. JSON은 일부 이진 파일이 아니기 때문에 읽기 가능한 텍스트이고 매우 유용 할 수 있습니다. 잘 UTF8 문자가 포함되어 있습니다.

을 선택해야하는 유효한 이유가 있거나 또는 라틴보다 다른 문자 집합에 대해 신경을 쓰지 않는 대다수의 사람들에 의해 발생한 나쁜 라이브러리 디자인의 광범위한 현상 일 수 있습니다. .

+0

ByteString은 텍스트보다 몇 년 앞선 것입니다. 의심 할 여지없이, 텍스트가 옵션이 아니었을 때 ByteString을 사용하기로 선택한 라이브러리가 꽤 많기 때문에 "잘못된 라이브러리 디자인"이라고 잘못 인용합니다. –

+0

@stephentetley 나는 그 단어와 downvote에 대해 불쾌감을 느낀 것을 이해하지 못합니다. 어쨌든 나는 비판하려하지 않고 단지 일을 정리하려고 노력했습니다. 가능한 역사적 이유에 대한 귀하의 발언이 도움이됩니다. –

+3

API 디자인에서 텍스트를 사용할 때 UTF8 인코딩을 사용하는 입력에 항상 의지 할 수 있어야합니다. 얼마나 많은 시간을 내가 그 가정을 만들었는지, 안전하고 건전한 느낌, 내 프로그램이 다른 인코딩을 나타 내기 위해 일어난 유효한 입력 (의미 적으로 문제 도메인에서 유효 함)에 대해 줄을 추락시키지 못했음을 말할 수 없습니다. 인터페이스가 텍스트 인 경우 더 이상 인코딩을 통해 프로그램 내부를 제어 할 수 없습니다. 대부분의 디자인에서 불필요하게 제한적이라는 것을 알았지 만 (물론 모든 것이 아닐지라도). – ozataman

답변

20

. 당신 printString를 포함하는 값, Char에 대한 Show 인스턴스가 사용

Prelude> print "Ёжик лижет мёд." 
"\1025\1078\1080\1082 \1083\1080\1078\1077\1090 \1084\1105\1076." 
Prelude> putStrLn "\1025\1078\1080\1082 \1083\1080\1078\1077\1090 \1084\1105\1076." 
Ёжик лижет мёд. 
Prelude> "{\"a\": \"Ёжик лижет мёд.\"}" 
"{\"a\": \"\1025\1078\1080\1082 \1083\1080\1078\1077\1090 \1084\1105\1076.\"}" 

, 그리고 당신이 원하는 문양을 얻으려면 127 위의 코드 포인트로 모든 문자를 이스케이프, 당신은 StringputStr[Ln]해야합니다.

encode = {-# SCC "encode" #-} encodeUtf8 . toLazyText . fromValue . 
     {-# SCC "toJSON" #-} toJSON 

그래서 aeson가 최종 타겟 ByteString하지 Text를 사용하는 이유는 질문 :이 때문에 예상 할 수있는 바와 같이

그래서 aeson 제대로는 UTF8 인코딩 된 입력을 디코딩 된 값 자체 UTF8 - 코딩 인코딩 및 디코딩 시작점.

이것이 적절한 유형입니다. 인코딩 된 값은 컴퓨터간에 이식 가능하도록 전송됩니다. 그것은 바이트의 흐름 (우리가 현학적 분위기라면)에 일어납니다. 정확히 ByteString이 제공하는 것으로서, 응용 프로그램 특정 방식으로 처리되어야하는 바이트 시퀀스입니다. aeson의 경우 바이트 스트림은 utf-8로 인코딩되어야하고 aesondecode 함수의 입력이 유효한 utf-8이라고 가정하고 해당 출력을 유효한 utf-8로 인코딩합니다.

예 : Text은 16 비트 인코딩이 엔디안 방식에 따라 다르므로 이식성 문제가 발생하므로 Text은 컴퓨터간에 데이터를 교환하는 데 적합한 형식이 아닙니다. aeson은 중간 단계에서 사용할 적절한 유형이기 때문에 인코딩 할 때 중간 유형으로 (그리고 아마도 디코딩 할 때도) Text을 사용합니다.

+0

이것은 많은 의미가 있습니다. 고맙습니다! 문제 추적기에 거짓 경보를 내린 것처럼 보입니다. –

+2

/my/network 전송에 대한 형식을 선택하는 것이 파서/송신자의 책임인지 나는 알 수 없습니다. 그것은 텍스트 데이터를 파싱하고, Data.Text는 UTF 인코딩을 생성하고 가져 오는 함수를 가지고 있습니다. 반면 Aeson은 UTF8로 인코딩 된 bytestrings을 구문 분석하는 것으로 제한됩니다. – nomen

2

JSON 표준은 UTF-8이 아니라 UTF-16으로 정산되었습니다. 자세한 내용은 공식 웹 사이트 http://json.org/에서 확인할 수 있습니다. (그리고 아이손의 추가 방어, JSON의 이진 비트의 인터페이스를 통해 노출되지 않습니다하십시오 ValueString 생성자가 Text 아닌 ByteString이 포함되어 있습니다.) 나는 your problem 그냥 오해라고 생각

+1

좋아요, 그래서 UTF16. '텍스트'UTF16, btw가 아닌가요? 다시, 나는 Aeson을 때리거나하지 않는다. 그러나 API에 대한 귀하의 관점에서 볼 때 매우 중심적인 장소에서 ByteString을 노출합니다. [encode/decode] (http://hackage.haskell.org/packages/archive/aeson/0.6.0.2/doc/ html/Data-Aeson.html # v : decode)입니다. 그래서 또 다시 궁금해합니다. 이유는 무엇입니까? 그 이유는 그 패키지의 저자가'텍스트'자체의 공동 저자이기 때문에 역사적인 것으로 보이지 않습니다. 네트워킹 관련 문제 일 수 있습니까? –

+0

Btw, [여기에 근본적으로 현재 질문 뒤에 숨어있는 문제] (https://github.com/bos/aeson/issues/105). –

+5

JSON 표준은 언제부터 UTF-16에 정착 했습니까? 2006 년 7 월 발표 된 RFC 4627에 따르면 "JSON 텍스트는 유니 코드로 인코딩되어야하며 기본 인코딩은 UTF-8입니다." 이 웹 사이트는 해당 문서에 연결되며 UTF 인코딩은 언급하지 않습니다. –