2010-08-05 68 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