Haskell,Char,Unicode和土耳其语

Jon*_*len 26 unicode text haskell localization internationalization

对于Char数据类型,如何指定我想将土耳其语i而不是英语i用于toLower和toUpper函数?

Don*_*art 16

文本和text-icu包

截至2011年,您最好的选择是使用文本包,以及Text ICU包toLower功能,它支持由语言环境参数化的操作,Char

这个例子:

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
Run Code Online (Sandbox Code Playgroud)

运行这个:

> toLower ÇI??Ö?Ü gives ç?i?ö?ü
Run Code Online (Sandbox Code Playgroud)

虽然此示例在两者之间进行转换String,但您也可以将数据保留为text格式.


grd*_*dev 15

Data.CharHaskell中的库不依赖于语言环境.它适用于所有Unicode字符,但可能不是您期望的方式.在相应的Unicode图表中,您可以看到"dotted"/"dotless"i的映射.

  • toUpper 'i' => 'I'
  • toUpper '?' => 'I'
  • toLower 'I' => 'i'
  • toLower '?' => 'i'

因此,很明显两个变换都不是可逆的.如果你想要对土耳其字符进行可逆处理,你似乎必须使用C库或自己动手.

更新:哈斯克尔98报告使得这个很清楚,而哈斯克尔2010年报告只是说Char相当于Unicode字符,并且不为明确界定的语义toLowertoUpper.

  • @Alexandre:我记录了Haskell的工作方式,以及(链接的)Unicode规范所说的内容.如果你想要其他行为,你需要实现自己的行为(如在jrockway的回复中). (2认同)

jro*_*way 7

一个简单的编程问题:

import qualified Data.Char as Char

toLower 'I' = '?'
toLower x   = Char.toLower x
Run Code Online (Sandbox Code Playgroud)

然后

toLower <$> "I AM LOWERCASE" == "? am lowercase"  
Run Code Online (Sandbox Code Playgroud)

  • @Jonathan:是的,因为Haskell规范只说遵循Unicode标准,它提供了我上面给出的规则.因此,任何使用`Char.toLower`的库都没有为国际化做好准备. (4认同)
  • 我应该澄清一点,这不是最好的解决办法.编写一个比Data.Char更灵活的库会更好,社区肯定会欣赏该领域的任何贡献. (3认同)
  • @Jonathan Allen:如果您不想要标准的 Unicode 行为,那么不,您不能使用遵循 Unicode 标准的库。这很不幸,但很明显就是这样。 (2认同)