2011-05-15 3 views
8

하스켈 (GHC)에있는 국가 별 문자로 문자열을 올바르게 정렬 할 수 있습니까? 바꾸어 말하면, 현재의 로케일 설정에 의한 Chars의 올바른 조합인가?하스켈의 로케일별로 문자열 정렬 및 비교?

ICU 모듈 만 찾았지만 Linux 배포판의 표준 부분이 아니기 때문에 추가 라이브러리가 필요합니다. POSIX의 C (glibc like) 라이브러리를 기반으로 한 솔루션을 원합니다. 따라서 추가 종속성을 다루는 번거 로움이 없습니다.

+0

당신은 wcscoll''에 바인딩 FFI를 쓸 수 있지만'텍스트 icu'를 사용하여 친절하고 아마 더 정확한 둘 다 할 수있다. – hammar

+0

좋은 질문과 좋은 답변. 인간의 물건은 절대로 순수한 기능이 아닙니다. –

답변

13

권장 방법 : 당신이 본대로 로케일에 민감한 방식으로 견고하게 처리하는 문자열에 대한 텍스트 ICU

권장되는 방법은, texttext-icu를 통해입니다. text 라이브러리는 표준 라이브러리 세트 Haskell Platform에 제공됩니다. 정렬

, 터키어 문자열 : 텍스트 -를 사용하지

*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) 

가 올바르게 정렬 lexicographic ordering에 의해 지역에 기반에 나타납니다 후 제대로 터키 문자열을 하위 케이싱 icu 패키지

귀하는 추가로 POSIX가 제공하는 것 이외의 다른 라이브러리. text-icu는 Hackage (cabal install text-icu)에서 쉽게 설치할 수 있지만 어디서나 사용할 수없는 ICU C 라이브러리에 의존합니다. 또한, 강력하거나 포괄적 인 Posix 대안이 없습니다. 마지막으로 text-icu은 다중 문자에서 올바르게 변환하는 유일한 패키지입니다.

, 그래도이 제공 하스켈에서 샤아와 문자열 유형에 지어진이 주어지면 그 값 유니 코드를 표현하고, will do Unicode case conversion, 로케일 구분하지 않는 방법으로, 오픈 그룹에 의해 정의 the wchar_t functions를 사용하여 기능 Data.Char. 또한 핸들에 대한 IO는 (텍스트) 로케일에 민감한 방식으로 처리 할 수 ​​있습니다.

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는 텍스트 로캘을 IO (예 : UTF8)로 사용합니다. 많은 문제에 대해, 이것은 아마도 정답을 줄 것입니다. 텍스트의 일괄 처리 및 풍부한 변환 및 비교 지원 없이는 정확하지 않을 수 있기 때문에 많은 경우에 잘못 될 수도 있습니다.

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

+1

그리고 'i'는 Char 솔루션과 다릅니다. –

+2

[이 기능들] (http://hackage.haskell.org/packages/archive/text-icu/0.6.3.3/doc/html/Data-Text-ICU.html#g)을 사용하는 것이 더 정확하지 않습니까? : 9) 지역별 데이터 정렬? – hammar

+0

또한'Char'의 toUpper는'LC_CTYPE' 로케일 설정을 기반으로 넓은 char 변환만을 수행합니다. 그래서 부분적으로 로케일 만 인식합니다. 그리고 언급했듯이 다중 문자 변환에는 실패합니다. –