2010-08-05 45 views
26

对于Char数据类型,如何指定我要使用土耳其语而不是英语i作为toLower和toUpper函数?Haskell,Char,Unicode和土耳其语

+7

已收藏。土耳其是棘手的,由于无问题我的问题。这是这种功能的最佳测试案例。 – 2010-08-05 11:53:09

+12

与正确处理Unicode相比,了解monads是一个Cakewalk。 – 2010-08-05 15:07:44

+4

@Alex:土耳其语?更不要说德语的多字母大写ß - > SS和希腊语的上下文相关小写Σ - >σ/ς。 – kennytm 2010-08-05 16:18:07

回答

16

文本和文本ICU包

截至2011年,最好的办法是使用text包,以及the Text ICU packagetoLower功能,它支持一个语言环境参数Char操作,

this example

import Data.Text (pack, unpack) 
import Data.Text.ICU (LocaleName(Locale), toLower) 

main = do 
    let trLocale = Locale "tr-TR" 
     upStr = "ÇIİĞÖŞÜ" 
     lowStr = unpack $ toLower trLocale $ pack upStr 
    putStrLn $ "toLower " ++ upStr ++ " gives " ++ lowStr 

运行此:

> toLower ÇIİĞÖŞÜ gives çıiğöşü 

尽管这个例子String之间的转换,你也可以只留在text格式的数据。

0

也许尝试设置您的语言环境?不确定

+5

语言环境对默认的'Data.Char'库没有影响。 – grddev 2010-08-05 08:40:26

+0

但是,语言环境会影响'Data.Text.ICU'包。 – 2011-04-22 17:41:57

15

Haskell中的Data.Char库与语言环境无关。它适用于所有Unicode字符,但可能不符合您的预期。在the corresponding Unicode chart你可以看到“dotted”/“dotless”i的映射。

  • toUpper 'i' =>'I'
  • toUpper 'ı' =>'I'
  • toLower 'I' =>'i'
  • toLower 'İ' =>'i'

因此,很明显,无论是两个变换是可逆的。如果你想要可逆的处理土耳其字符,看起来你必须使用C库或者自己编辑。

UPDATE:Haskell 98 report使这很清楚,而Haskell 2010 report只说Char对应的Unicode字符,并且不为明确界定的toLowertoUpper语义。

+0

'下来'我'应该给一个无点'我'。 – 2010-08-05 16:42:13

+2

@Alexandre:我记录了Haskell是如何工作的,以及(链接的)Unicode规范说的。如果你想要其他行为,你需要实现你自己的(如在Jrockway的回复中)。 – grddev 2010-08-05 17:22:21

7

一个简单的问题编程:

import qualified Data.Char as Char 

toLower 'I' = 'ı' 
toLower x = Char.toLower x 

然后

toLower <$> "I AM LOWERCASE" == "ı am lowercase" 
+0

您是否确实告诉我,为了支持国际化,我必须破解每个调用Char.toLower的库? – 2010-08-05 18:48:12

+4

@Jonathan:是的,因为Haskell规范只是说遵循Unicode标准,它提供了我在上面给出的规则。因此,任何使用'Char.toLower'的库都不适合国际化。 – grddev 2010-08-05 19:04:59

+1

@Jonathan Allen:如果你不想要标准的Unicode行为,那么不行,你不能使用遵循Unicode标准的库。这很不幸,但很明显。 – Chuck 2010-08-05 23:47:41