2011-05-15 115 views
8

是否可以在Haskell(GHC)中用國家字符對字符串進行正確排序?換句話說,通過當前語言環境設置對Chars進行正確的排序?按照Haskell中的區域設置對字符串進行排序和比較?

我確實發現了ICU模塊,但它需要安裝額外的庫,因爲它不是Linux發行版的標準部分。我想要基於POSIX的C(glibc like)庫的解決方案,所以不會有任何處理額外依賴的麻煩。

+0

你可以寫一個FFI結合'wcscoll',但使用'文本icu'既漂亮,可能更正確。 – hammar 2011-05-15 22:48:51

+0

好問題,很好的答案。人的東西從來不是一個純粹的功能。 – 2011-05-16 18:42:35

回答

13

推薦方式:文字ICU

的建議方式對語言環境敏感的方式處理強勁的字符串是通過texttext-icu,正如你所看到的。 text庫在標準庫集中提供,Haskell Platform

一個例子,排序土耳其字符串:

{-# LANGUAGE OverloadedStrings #-} 

import Data.Text.IO as T 
import Data.Text.ICU as T 
import Data.List  (sortBy) 

main = do 
    let trLocale = T.Locale "tr-TR" 
     str  = "ÇIİĞÖŞÜ" 
     strs  = take 10 (cycle $ T.toLower trLocale str : str : []) 

    mapM_ T.putStrLn (sortBy (T.compare [T.FoldCaseExcludeSpecialI]) strs) 

似乎正常排序lexicographic ordering基於區域,之後正確較低殼體土耳其字符串:

*Main> main 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
çıiğöşü 
çıiğöşü 
çıiğöşü 
çıiğöşü 
çıiğöşü 

不使用文本的icu包裝

您已經在您的問題中詢問過要避免使用add除了Posix提供的外,它還有其它庫。儘管可以從Hackage(cabal install text-icu)輕鬆安裝text-icu,但它依賴於ICU C庫,該庫在任何地方都不可用。另外,沒有任何Posix替代品是穩健的或全面的。最後,text-icu是在多字符字符上正確進行轉換的唯一軟件包。

鑑於此,雖然內置的字符和字符串類型在Haskell提供Data.Char,它們的值表示的Unicode,並與will do Unicode case conversion,在一個語言環境不敏感的方式,使用由Open Group定義the wchar_t functions功能。另外,我們可以以(文本)區域敏感的方式在句柄上執行IO。

import System.IO 
import Data.Char 
import Data.List (sort) 

main = do 
    t <- mkTextEncoding "UTF-8" 
    hSetEncoding stdout t 

    let str  = "ÇIİĞÖŞÜ" 
     strs  = take 10 (cycle $ map toLower str : str : []) 

    mapM_ putStrLn (sort strs) 

事實上,GHC將默認使用您的文本區域設置用於IO(例如UTF8)。對於很多問題,這可能會給出正確的答案。你必須意識到在很多情況下它也是錯誤的,因爲如果沒有批量處理文本和豐富的轉換和比較支持,它是不可能正確的。

*Main> main 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
çiiğöşü 
çiiğöşü 
çiiğöşü 
çiiğöşü 
çiiğöşü 

+1

並注意在Char解決方案中'i'是不同的。 – 2011-05-15 22:51:23

+2

使用[這些函數]會不會更正確(http://hackage.haskell.org/packages/archive/text-icu/0.6.3.3/doc/html/Data-Text-ICU.html#g :9)針對特定地區的整理? – hammar 2011-05-15 23:02:21

+0

另請注意,僅在'Char'上執行寬字符轉換,基於'LC_CTYPE'語言環境設置。所以它只有部分區域意識。如前所述,多字符轉換失敗。 – 2011-05-15 23:03:21

相關問題