Haskell 中的 Utf8 和重载字符串
Utf8 and overloaded strings in Haskell
我意识到我的文本中的重音会转换为 �。
我把它归结为以下示例
写入(并覆盖)文件 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
"Universit3"
这已经编码错误了吗?我还在 � 中找到了一条评论
https://hackage.haskell.org/package/text-1.2.2.2/docs/Data-Text.html,
但我仍然不知道如何更正上面的例子。
如何在 OverloadedString 中使用重音符号并将它们正确写入文件?
这与 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 不是最新的。不过,应该可以在任何编辑器中手动 select 编码。
事实上,Data.Text.IO.writeFile
现在将使用您的 locale to decide how to encode the file. Everybody should have UTF-8 作为他们的语言环境,如果您不这样做,请更改它。
要在您的文件中获取 BOM,从而排除此类问题,请使用 utf8_bom
。
关于您在 GHCi 中看到的输出:那是正在工作的 Show
实例;它将任何类似字符串的值转义为最安全的形式,即任何不是 ASCII 的转义序列,'é'
恰好是 '3'
。再次不特定于 Text
,事实上,即使是单个字符,你也会得到这个:
Prelude> 'é'
'3'
Prelude> putChar '3'
é
当您对字符串类型使用直接 IO 输出操作时,这种转义永远不会发生,即 putChar
、putStr
或 putStrLn
.
Prelude> import qualified Data.Text.IO as Txt
Prelude Txt> Txt.putStrLn "Université"
Université
我意识到我的文本中的重音会转换为 �。 我把它归结为以下示例 写入(并覆盖)文件 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
"Universit3"
这已经编码错误了吗?我还在 � 中找到了一条评论 https://hackage.haskell.org/package/text-1.2.2.2/docs/Data-Text.html, 但我仍然不知道如何更正上面的例子。
如何在 OverloadedString 中使用重音符号并将它们正确写入文件?
这与 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 不是最新的。不过,应该可以在任何编辑器中手动 select 编码。
事实上,Data.Text.IO.writeFile
现在将使用您的 locale to decide how to encode the file. Everybody should have UTF-8 作为他们的语言环境,如果您不这样做,请更改它。
要在您的文件中获取 BOM,从而排除此类问题,请使用 utf8_bom
。
关于您在 GHCi 中看到的输出:那是正在工作的 Show
实例;它将任何类似字符串的值转义为最安全的形式,即任何不是 ASCII 的转义序列,'é'
恰好是 '3'
。再次不特定于 Text
,事实上,即使是单个字符,你也会得到这个:
Prelude> 'é'
'3'
Prelude> putChar '3'
é
当您对字符串类型使用直接 IO 输出操作时,这种转义永远不会发生,即 putChar
、putStr
或 putStrLn
.
Prelude> import qualified Data.Text.IO as Txt
Prelude Txt> Txt.putStrLn "Université"
Université