Haskell, Char, Unicode, and Turkish

前端 未结 3 1327
借酒劲吻你
借酒劲吻你 2020-12-28 14:46

For the Char data-type, how do I specify that I want to use the Turkish i instead of the English i for the toLower and toUpper functions?

相关标签:
3条回答
  • 2020-12-28 14:52

    The Data.Char library in Haskell is not locale dependent. It works for all Unicode characters, but perhaps not in the way you would expect. In the corresponding Unicode chart you can see the mappings for "dotted"/"dotless" i's.

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

    Thus, it is clear that neither of the two transforms are reversible. If you want reversible handling of Turkish characters, it seems you have to use either a C-library or roll your own.

    UPDATE: The Haskell 98 report makes this quite clear, whereas the Haskell 2010 report only says that Char corresponds to a Unicode character, and does not as clearly define the semantics of toLower and toUpper.

    0 讨论(0)
  • 2020-12-28 15:12

    A Simple Matter Of Programming:

    import qualified Data.Char as Char
    
    toLower 'I' = 'ı'
    toLower x   = Char.toLower x
    

    Then

    toLower <$> "I AM LOWERCASE" == "ı am lowercase"  
    
    0 讨论(0)
  • 2020-12-28 15:14

    text and the text-icu package

    As of 2011, your best bet is to use the text package, and the toLower function of the Text ICU package, which supports Char operations parameterized by a locale,

    From 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
    

    Running this:

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

    while this example converts between String, you can also just leave the data in text format.

    0 讨论(0)
提交回复
热议问题