Рекомендуемый способ: text-icu
Рекомендованный способ надежной обработки строк с учетом языка - через text и text-icu , так как вы видел. Библиотека text поставляется в стандартном наборе библиотек Haskell Platform .
Пример, сортировка турецких строк:
{-# LANGUAGE OverloadedStrings #-}
import Data.Text.IO as T
import Data.Text.ICU as T
import Data.List (sortBy)
main = do
let trLocale = T.Locale "tr-TR"
str = "ÇIİĞÖŞÜ"
strs = take 10 (cycle $ T.toLower trLocale str : str : [])
mapM_ T.putStrLn (sortBy (T.compare [T.FoldCaseExcludeSpecialI]) strs)
, по-видимому, правильно сортирует по лексикографическому порядку на основе локали, после правильной строчной турецкой строки:
*Main> main
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
çıiğöşü
çıiğöşü
çıiğöşü
çıiğöşü
çıiğöşü
Не используется пакет text-icu
Вы задали в своем вопросе, чтобы избежать решений, которые используют дополнительные библиотеки, помимо того, что предоставляет Posix. Хотя text-icu легко установить из Hackage (cabal install text-icu
), он зависит от библиотеки ICU C, которая доступна не везде. Кроме того, не существует альтернативы Posix, которая была бы настолько надежной или всеобъемлющей. Наконец, text-icu
является единственным пакетом, который правильно выполняет преобразования для символов из нескольких символов.
Однако, учитывая это, встроенные в Haskell типы Char и String предоставляют Data.Char , значения которого представляют Unicode, и с функциями, которые будут выполнять преобразование регистра Unicode нечувствительный к локали способ с использованием функций wchar_t
, определенных Open Group. Кроме того, мы можем выполнять ввод-вывод для дескрипторов (текст) с учетом языка.
import System.IO
import Data.Char
import Data.List (sort)
main = do
t <- mkTextEncoding "UTF-8"
hSetEncoding stdout t
let str = "ÇIİĞÖŞÜ"
strs = take 10 (cycle $ map toLower str : str : [])
mapM_ putStrLn (sort strs)
Фактически, GHC будет использовать ваш текстовый языковой стандарт по умолчанию для ввода-вывода (например, UTF8). Для многих проблем это, вероятно, даст правильный ответ. Вам просто нужно знать, что во многих случаях это также будет неправильно, поскольку невозможно быть правильным без массовой обработки текста и расширенной поддержки преобразования и сравнения.
*Main> main
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
ÇIİĞÖŞÜ
çiiğöşü
çiiğöşü
çiiğöşü
çiiğöşü
çiiğöşü