String 在Haskell中按区域设置对字符串进行排序和比较?
是否可以在Haskell(GHC)中正确地对带有国家字符的字符串进行排序?换句话说,按当前区域设置正确排序字符String 在Haskell中按区域设置对字符串进行排序和比较?,string,haskell,localization,locale,String,Haskell,Localization,Locale,是否可以在Haskell(GHC)中正确地对带有国家字符的字符串进行排序?换句话说,按当前区域设置正确排序字符 我确实只找到了ICU模块,但它需要安装额外的库,因为它不是linux发行版的标准部分。我希望解决方案基于POSIX的C(类似glibc的)库,这样就不会有处理额外依赖项的麻烦。推荐方式:text icu 如您所见,建议通过和以区域设置敏感的方式稳健地处理字符串。该库在标准库集中提供,即 例如,排序土耳其字符串: {-# LANGUAGE OverloadedStrings #-} i
我确实只找到了ICU模块,但它需要安装额外的库,因为它不是linux发行版的标准部分。我希望解决方案基于POSIX的C(类似glibc的)库,这样就不会有处理额外依赖项的麻烦。推荐方式:text icu 如您所见,建议通过和以区域设置敏感的方式稳健地处理字符串。该库在标准库集中提供,即 例如,排序土耳其字符串:
{-# 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)
在正确下套管土耳其管柱后,根据区域设置正确排序:
*Main> main
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
çıiğöşü
çıiğöşü
çıiğöşü
çıiğöşü
çıiğöşü
不使用文本icu包
您在问题中要求避免使用Posix提供的库以外的其他库的解决方案。虽然文本icu很容易从Hackage安装(cabal install text icu
),但它确实依赖于icu C库,而icu C库并非无处不在。此外,没有比Posix更健壮、更全面的替代方案。最后,text-icu
是唯一能够正确转换多字符的软件包
尽管如此,Haskell中内置的Char和String类型提供了一些函数,这些函数的值表示Unicode,并且以不区分区域设置的方式使用OpenGroup定义的函数。此外,我们可以以(文本)区域设置敏感的方式对句柄执行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)
您可以将FFI绑定到
wcscoll
,但使用文本icu
则更好,而且可能更正确。问得好,回答得好。Human stuff从来都不是一个纯函数。请注意,i
在字符解决方案中是不同的。使用特定于区域设置的排序规则不是更正确吗?还要注意,Char
上的toUpper仅基于LC\u CTYPE
区域设置进行宽字符转换。因此,它只是部分地区感知。如前所述,多字符转换失败。@hammar是的,我认为您可能应该使用经批准的排序方法。
*Main> main
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
çiiğöşü
çiiğöşü
çiiğöşü
çiiğöşü
çiiğöşü