似乎 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/