Haskell, Char, Unicode, and Turkish
For the Char data-type, how do I specify tha开发者_如何学JAVAt I want to use the Turkish i instead of the English i for the toLower and toUpper functions?
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.
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
.
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"
精彩评论