2011-05-15 171 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

相关问题