Utf8和Haskell中重载的字符串

时间:2017-08-27 12:22:07

标签: haskell utf-8 overloaded-strings

我意识到我的文本中的重音会转换为 。 我把它煮成了下面的例子,其中 写入(并覆盖)文件test.txt。

它只使用Data.Text中的方法 处理unicode文本。我检查了两个源文件 以及输出文件以utf8编码。

{-# LANGUAGE OverloadedStrings #-}

import Prelude hiding (writeFile)
import Data.Text
import Data.Text.IO

someText :: Text
someText = "Université"

main :: IO ()
main = do 
    writeFile "test.txt" someText

运行代码后,test.txt包含:Universit 。 在ghci中,我得到以下内容

*Main> someText
"Universit\233"

这已编码错误吗?我还发现了对 in的评论 https://hackage.haskell.org/package/text-1.2.2.2/docs/Data-Text.html, 但我仍然不知道如何纠正上面的例子。

如何在OverloadedString中使用重音并正确地将它们写入文件?

1 个答案:

答案 0 :(得分:5)

这与Data.Text无关,当然也与OverloadedStrings无关 - 两者都处理UTF-8-Unicode就好了。

Data.Text.IO不会写BOM或任何表示编码的内容,即文件实际上只包含文本。在任何现代系统中,这意味着它将采用原始的UTF-8形式:

sagemuej@sagemuej-X302LA:~$ xxd test.txt 
00000000: 556e 6976 6572 7369 74c3 a9              Universit..
sagemuej@sagemuej-X302LA:~$ cat test.txt 
Université

因此,根据您打开文件的编辑器,可能会猜错编码,这显然是您的问题。在Linux上,UTF-8长期以来一直是标准,所以这里没有问题,但Windows并不是最新的。不过,应该可以在任何编辑器中手动选择编码。

事实上,Data.Text.IO.writeFile将使用您的locale来决定如何对文件进行编码。 Everybody should have UTF-8现在作为他们的语言环境,如果你不想改变它。

要在文件中获取BOM并排除此类问题,请使用utf8_bom

关于你在GHCi中看到的输出:Show实例在工作;它将任何类似字符串的值转换为最安全的可想象的形式,即对于'é'碰巧为'\233'的转义序列不是ASCII的任何东西。同样不是Text特有的,事实上即使对于单个字符也是如此:

Prelude> 'é'
'\233'
Prelude> putChar '\233'
é

当您对字符串类型使用direct-IO-output操作时,这种转义永远不会发生,即putCharputStrputStrLn

Prelude> import qualified Data.Text.IO as Txt
Prelude Txt> Txt.putStrLn "Université"
Université