2010-08-05 19 views
26

Para el tipo de datos Char, ¿cómo especifico que quiero utilizar el i turco en lugar del inglés i para las funciones toLower y ToUpper?Haskell, Char, Unicode y turco

+7

Favorito. El turco es complicado debido a problemas sin punto. Es el mejor caso de prueba para tales funciones. –

+12

Comprender las mónadas es un juego de niños en comparación con el manejo correcto de Unicode. –

+4

@Alex: ¿Turco? Sin mencionar las mayúsculas y minúsculas alemanas ß -> SS y las minúsculas griegas dependientes del contexto Σ -> σ/ς. – kennytm

Respuesta

16

texto y el paquete de texto-UCI

A partir de 2011, la mejor opción es utilizar el paquete text, y la función toLower de the Text ICU package, que apoya Char operaciones parametrizado por un local,

De 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 

la ejecución de este:

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

mientras que este ejemplo se convierte entre String, también puede dejar los datos en formato text.

0

tal vez intente configurar su configuración regional? no estoy seguro

+5

La configuración regional no tiene ningún impacto en la biblioteca 'Data.Char' predeterminada. – grddev

+0

Sin embargo, la configuración regional afecta al paquete 'Data.Text.ICU'. –

15

La biblioteca Data.Char en Haskell no depende de la configuración regional. Funciona para todos los caracteres Unicode, pero quizás no de la manera esperable. En the corresponding Unicode chart, puede ver las asignaciones de "puntos"/"sin punto".

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

Por lo tanto, es claro que ninguna de las dos transformadas son reversibles . Si desea un manejo reversible de caracteres turcos, parece que tiene que usar una biblioteca C o hacer su propia.

ACTUALIZACIÓN: ElHaskell 98 report hace esto muy claro, mientras que el Haskell 2010 report sólo dice que Char corresponde a un carácter Unicode, y no define claramente como la semántica de toLower y toUpper.

+0

'toLower 'I'' debería dar un' i' sin puntos. –

+2

@Alexandre: documenté cómo funciona Haskell y qué dice la especificación Unicode (vinculada). Si quieres otro comportamiento, debes implementar el tuyo (como en la respuesta de jrockway). – grddev

7

una simple cuestión de programación:

import qualified Data.Char as Char 

toLower 'I' = 'ı' 
toLower x = Char.toLower x 

Entonces

toLower <$> "I AM LOWERCASE" == "ı am lowercase" 
+0

¿Realmente me está diciendo que tengo que hackear cada biblioteca que llame a Char.toLower para apoyar la internacionalización? –

+4

@Jonathan: Sí, porque la especificación Haskell solo dice que sigas el estándar Unicode, que proporciona las reglas que di más arriba. Por lo tanto, cualquier biblioteca que use 'Char.toLower' no está preparada para la internacionalización. – grddev

+1

@Jonathan Allen: si no desea el comportamiento estándar de Unicode, entonces no, no puede usar bibliotecas que sigan el estándar Unicode. Es desafortunado, pero bastante claro. – Chuck