2011-05-15 16 views
8

Dizeleri Haskell (GHC) 'deki ulusal karakterlerle doğru şekilde sıralamak mümkün mü? Diğer bir deyişle, Chars'ın geçerli yerel ayarlara göre doğru harmanlanması?Haskell'de dizeleri yerel dizilere göre sıralama ve karşılaştırma?

Yalnızca ICU modülünü buldum, ancak linux dağıtımlarının standart bir parçası olmadığı için yüklenmesi gereken ek kitaplık gerektirir. POSIX'in C (glibc like) kitaplığına dayanan bir çözüm isterim, bu nedenle ek bağımlılık ile uğraşmak zorunda kalmazsınız.

+0

Sen wcscoll' 'bağlanarak bir FFI yazmak, ancak' metin icu' kullanarak daha güzel ve muhtemelen daha doğru hem de olabilir. – hammar

+0

İyi soru ve iyi cevap. İnsan şeyleri asla saf bir işlev değildir. –

cevap

13

Önerilen yol: Eğer gördüğümüz gibi bir yerel duyarlı bir şekilde sağlam işleme dizeleri metin icu

önerilen yolu, text ve text-icu yoluyladır. text kitaplığı, standart kitaplık kümesinde, Haskell Platform'da sağlanır. sıralama

bir örnek

, Türk dizeleri: yanıt sistemi kullanmama

*Main> main 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
çıiğöşü 
çıiğöşü 
çıiğöşü 
çıiğöşü 
çıiğöşü 

:

{-# 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) 

doğru sıralama lexicographic ordering tarafından yerel ayara dayalı görünüyor, sonra düzgün Türk dize alt Kılıf icu paketi

Sorunu kullanmak için kullandığınız çözümlerden kaçınmak için sorunuzu sordunuz Posix'in sağladığı şeyden başka, bağımsız kütüphaneler. Text-icu, Hackage'den (cabal install text-icu) kolayca yüklenirken, her yerde mevcut olmayan ICU C kitaplığına bağlıdır. Ek olarak, sağlam veya kapsamlı bir Posix alternatifi yoktur. Son olarak, text-icu, çoklu karakter karakterleri üzerinde doğru şekilde dönüşüm gerçekleştiren tek pakettir.

olsa sağlamak Haskell Char ve dize türleri inşa edilmiş olan bu Verilen, değerleri Unicode temsil eder ve will do Unicode case conversion, bir yerel-duyarsız bir şekilde, aç Group tarafından tanımlanan the wchar_t functions kullanarak fonksiyonları ile Data.Char. Ek olarak, Tutamaçlarda IO'ları (metin) yerel olarak duyarlı bir şekilde yapabiliriz.

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) 

Aslında, GHC IO (örn UTF8) için varsayılan olarak metin yerel ayarı kullanır. Birçok problem için, bu muhtemelen doğru cevabı verecektir. Metinlerin toplu işlenmesi ve zengin dönüşüm ve karşılaştırma desteği olmaksızın doğru olması mümkün olmadığından, çoğu durumda da yanlış olabileceğinin farkında olmanız gerekir.

*Main> main 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
ÇIİĞÖŞÜ 
çiiğöşü 
çiiğöşü 
çiiğöşü 
çiiğöşü 
çiiğöşü 

+1

Ve “i” nin Char çözümünde farklı olduğunu fark edin. –

+2

[bu işlevler] kullanmak daha doğru olmaz mıydı (http://hackage.haskell.org/packages/archive/text-icu/0.6.3.3/doc/html/Data-Text-ICU.html#g : 9) yerel özel harmanlama için? – hammar

+0

Ayrıca "Char" üzerindeki toUpper, "LC_CTYPE" yerel ayarına bağlı olarak yalnızca geniş bir dönüşüm gerçekleştirir. Yani sadece kısmen yerel olarak farkında. Ve belirtildiği gibi, çoklu char dönüşümleri için başarısız olur. –

İlgili konular