簡體   English   中英

Haskell:如何檢查 char 是否有效 utf8

[英]Haskell: How to check that a char is valid utf8

如何檢查 haskell 中的Char是否是有效的 UTF8 代碼點?

我有一個 class 正在生成字符串,受一些約束,以及該 class 的Arbitrary實例(僅生成滿足這些約束的字符串)。 我正在使用GenValidity 但是 String 的標准生成器偶爾會生成無效字符; 例如'\xed' 不出所料,這會在以后引起問題。

“無效”是指Data.Text.Encoding.streamDecodeUtf8標記錯誤:

λ> streamDecodeUtf8 (Data.ByteString.Char8.pack "\xed")
Some "" "\237" _

我想向我的 GenValidity 實例添加一個基於(假設的) isValidUTF8:: Char -> Bool function 的約束,但令人驚訝的是,我找不到任何匹配項。 我能做的最好的ATM是

((\ (Data.Text.Encoding.Some _ x _) -> x /= "") . Data.Text.Encoding.streamDecodeUtf8With (\ _ _ -> Nothing) . Data.ByteString.Char8.pack) . pure

這肯定是相當重量級的,我擔心轉換為 ByteString,然后轉換為 Text,可能會引入尖銳的邊緣。

我很驚訝我找不到更好的/預先罐裝的東西。

歡迎咨詢和指點!

這些示例按預期工作。

“如何檢查Char是否為有效的 UTF-8”這個問題沒有任何意義(但你不能因為不知道你不知道什么而受到責備)。 它基於對 UTF-8 是什么的誤解。 UTF-8 是一種編碼:它描述了一種將這些代碼點轉換為字節的方法,這些字節可以存儲或通過網絡發送。

打個比方,這就像問“如何檢查Integer是否有效以 10 為基數”。 想想為什么這沒有意義。

編碼是“具體數據”的屬性,如“字節串”(字節序列,這是 Haskell 中的ByteString類型)。 一旦這些字節被解碼,我們就只有“文本”,並且 UTF-8 不再是該抽象級別的相關概念(代碼點序列( Char ),這是 Haskell 中的TextString )。

但是 String 的標准生成器偶爾會生成無效字符; 比如'\xed'。

所有Char都有效[1] Unicode 代碼點。 參見文檔。'\xed'是代碼點編號 237。

[1]:對於“有效”的一些定義...... Unicode 隱藏了很多復雜性。

“無效”是指Data.Text.Encoding.streamDecodeUtf8標記錯誤:

 λ> streamDecodeUtf8 (Data.ByteString.Char8.pack "\xed") Some "" "\237" _

streamDecodeUtf8旨在應用於 UTF-8 字節串,但Data.ByteString.Char8.pack不會產生 UTF-8。 Char8.pack更像是一種模擬字節串文字的技巧; 它濫用 Unicode 來解決這樣一個事實,即在 Haskell 中,只有 Unicode 字符串的文字。 但是在這里你不想生成任意字節,所以不要使用Char8.pack

要對文本進行編碼,請使用Data.Text.Encoding模塊中的編碼函數之一。 正如我們所看到的,不同的編碼有不同的功能,這進一步說明了“編碼”不是文本固有的屬性,而是與它在 memory( ByteString公開)中的表示有關。

ghci> import Data.Text (pack)
ghci> import Data.Text.Encoding
ghci> streamDecodeUtf8 (encodeUtf8 (Data.Text.pack "\xed"))
Some "\237" "" _

我很驚訝我找不到更好的/預先罐裝的東西。

關於 Haskell 中的文本和整個編程有很多抱怨,但在這種情況下,問題源於對 Unicode 的誤解。 錯不在你身上,如果你還不熟悉這個系統,它肯定不明顯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM