haskell - GHC/Haskell 如何决定它将从/到解码/编码的字符编码?

标签 haskell character-encoding ghc

似乎 GHC 至少在它决定解码的字符编码方面是不一致的。

考虑一个文件,omatase-shimashita.txt ,内容如下,UTF-8编码:お待たせしました
readFile似乎正确地阅读了这个......

Prelude> content <- readFile "/home/chris/Desktop/omatase-shimashita.txt"
Prelude> length content
8
Prelude> putStrLn content
お待たせしました

但是,如果我编写一个简单的“echo”服务器,它不会使用默认的 UTF-8 进行解码。考虑以下处理传入客户端的代码:
handleClient handle = do
  line <- hGetLine handle
  putStrLn $ "Read following line: " ++ toString line
  handleClient handle

以及相关的客户端代码,显式发送 UTF-8:
Data.ByteString.hPutStrLn handle $ Codec.Binary.UTF8.Generic.fromString "お待たせしました"

这不是不一致的行为吗?有什么方法可以解决这种疯狂吗?我计划重写我的应用程序以明确使用 ByteString对象并使用 Codec.Binary.UTF8 显式编码和解码,但无论如何最好知道这里发生了什么......:o/

更新:我在 Ubuntu Linux 版本 10.10 上运行,语言环境为 en_US.UTF-8 ...
$ cat /etc/default/locale 
LANG="en_US.UTF-8"
$ echo $LANG 
en_US.UTF-8

最佳答案

您使用的是哪个版本的 GHC?旧版本尤其不能很好地完成 unicode I/O。

GHC 文档中的这一部分描述了如何更改输入/输出编码:

http://haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/System-IO.html#23

此外,文档是这样说的:

A text-mode Handle has an associated TextEncoding, which is used to decode bytes into Unicode characters when reading, and encode Unicode characters into bytes when writing.

The default TextEncoding is the same as the default encoding on your system, which is also available as localeEncoding. (GHC note: on Windows, we currently do not support double-byte encodings; if the console's code page is unsupported, then localeEncoding will be latin1.)

Encoding and decoding errors are always detected and reported, except during lazy I/O (hGetContents, getContents, and readFile), where a decoding error merely results in termination of the character stream, as with other I/O errors.



也许这与您的问题有关?如果 GHC 在某处默认为 utf-8 以外的内容,或者您​​的句柄已手动设置为使用不同的编码,这可能会解释问题。如果您只是想在控制台上回显文本,那么可能是某种控制台代码页的有趣之处正在发生。我知道我过去在使用其他语言(如 Python)和在 Windows 控制台中打印 unicode 时也遇到过类似的问题。

尝试运行 hSetEncoding handle utf8看看它是否能解决你的问题。

关于haskell - GHC/Haskell 如何决定它将从/到解码/编码的字符编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5286860/

相关文章:

haskell - 使用 Haskell 的 zip-conduit 从 zip 存档中的文件中读取行

javascript - 将unicode转为汉字

Haskell 异常 : Prelude. Enum.().toEnum:错误的参数

haskell - Cloud Haskell 中的 ManagedProcess 如何工作?

java - 瑞典语文本(vår、än、tall)。尝试发送邮件。但是在接收邮件时,在 Linux 环境中观察到问号(?)

c++ - 如何在 Windows API 中指定与编码无关的字符串常量?

performance - 蛮力旅行商: Why is Haskell so much slower than C?

haskell - dataToTag 参数的严格性

haskell - 当构造函数静态已知时消除 GADT 上的模式匹配

list - 将事物列表转换为子列表列表