Haskell Data.Yaml UTF-8 декодирование - PullRequest
1 голос
/ 09 ноября 2019

Я пытаюсь декодировать файл yaml, содержащий строки UTF-8, используя Data.Yaml. Это душит UTF-8. Я сузил пример к этому:

λ> :m + Data.ByteString
λ> :m + Data.Yaml
λ> :set -XOverloadedStrings 
λ> :set -XScopedTypeVariables 
λ> :set -XTypeApplications 
λ> let t :: ByteString  = "α"
λ> t
"\177"
λ> decodeEither' @Value t
Left (InvalidYaml (Just (YamlParseException {yamlProblem = "invalid leading UTF-8 octet", yamlContext = "", yamlProblemMark = YamlMark {yamlIndex = 0, yamlLine = 0, yamlColumn = 0}})))

Я пробовал разные ByteStrings (Char8, UTF8 из пакета utf8-string), но с тем же результатом.

Моя локальустановить в UTF8:

$ env | grep LANG
LANG=en_GB.UTF-8

Что я делаю не так?

Спасибо,

1 Ответ

0 голосов
/ 09 ноября 2019

Похоже, что в вашем примере строка байтов является усеченной версией исходной обычной строки. Греческая строчная буква «α» - это символ Unicode # 945, и она выглядит как просто код 177, а у нас 945 == (3 * 256) + 177.

 λ> 
 λ> :m Data.Char
 λ> :m + Data.ByteString
 λ> :set -XScopedTypeVariables 
 λ> :set -XOverloadedStrings 
 λ> 
 λ> Prelude.map ord "Aα"
 [65,945]
 λ> 
 λ> 177 + (3*256)
 945
 λ> 
 λ> let t1 :: ByteString  = "α"
 λ> 
 λ> :t t1
 t1 :: ByteString
 λ> t1
 "\177"
 λ> Data.ByteString.length t1
 1
 λ> 

Основная причина может бытьчто стиль кодирования UTF8 не имеет особых привилегий. Следовательно, необходимо четко указать тип ожидаемой конвертации в байтовую строку:

 λ> import Data.ByteString.UTF8 as BSUTF8
 λ> 
 λ> t2  = BSUTF8.fromString "α"
 λ> 
 λ> :t t2
 t2 :: ByteString
 λ> 
 λ> t2
 "\206\177"
 λ> 
 λ> Data.ByteString.length t2
 2
 λ> 
 λ> Prelude.putStrLn $ BSUTF8.toString t2
 α
 λ> 
 λ> :set -XTypeApplications
 λ> 
 λ> :m +Data.Yaml
 λ> 
 λ> Data.Yaml.decodeEither' @String  t2
 Right "\945"
 λ> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...