E / S de consola Unicode en Haskell en Windows

Parece bastante difícil lograr que la E / S de la consola funcione con los caracteres Unicode en Haskell en Windows. Aquí está la historia de la aflicción:

(Preliminar). Antes de que incluso considere la posibilidad de realizar Unicode I / O en la consola en Windows, debe asegurarse de que está utilizando una fuente de consola que pueda representar los caracteres que desea. Las fuentes de trama (las predeterminadas) tienen una cobertura infinitamente deficiente (y no permiten el copiado de caracteres que no pueden representar), y las opciones de truetype que proporciona MS (consolas, lucida console) no tienen una gran cobertura (aunque éstas permitirán Copiar / pegar de caracteres que no pueden representar). Podría considerar la instalación de DejaVu Sans Mono (siga las instrucciones que se encuentran en la parte inferioraquí; puede que tenga que reiniciar antes de que funcione). Hasta que esto no esté ordenado, ninguna aplicación podrá hacer mucho I / O de Unicode; no solo haskellUna vez hecho esto, notará que algunas aplicaciones podrán realizar la E / S de la consola en Windows. Pero hacerlo funcionar sigue siendo bastante complicado. Hay básicamente dos formas de escribir en la consola en Windows. (Lo que sigue es cierto para cualquier idioma, no solo Haskell; no te preocupes, ¡Haskell entrará en la imagen un poco!) ...La opción A es utilizar las funciones de E / S basadas en bytes de estilo de biblioteca C habituales; la esperanza es que el sistema operativo interpretará estos bytes de acuerdo con alguna codificación que pueda codificar todos los caracteres extraños y maravillosos que desee. Por ejemplo, utilizando la técnica equivalente en Mac OS X, donde la codificación del sistema estándar suele ser UTF8, esto funciona muy bien; Envías salida de utf8, ves símbolos bonitos.En las ventanas, funciona menos bien. La codificación predeterminada que espera Windows generalmente no será una codificación que cubra todos los símbolos de Unicode. Así que si quieres ver símbolos bonitos de esta manera, de una manera u otra, necesitascambio la codificacion Una posibilidad sería que su programa utiliceSetConsoleCP comando de win32 (Entonces, debe vincularse a la biblioteca de Win32). O, si prefiere no hacerlo, puede esperar que el usuario de su programa cambie la página de códigos por usted (entonces tendrían que llamar alchcp comando antes de que ejecuten su programa).La opción B es utilizar los comandos de la API de la consola win32 compatible con Unicode, comoWriteConsoleW. Aquí envía UTF16 directamente a las ventanas, lo que lo hace feliz: no hay peligro de una falta de coincidencia de codificación porque las ventanassiempre espera UTF16 con estas funciones.

Desafortunadamente, ninguna de estas opciones funciona muy bien desde Haskell. Primero, no hay bibliotecas que yo sepa que usen la Opción B, así que no es muy fácil. Esto deja la opción A. Si usa la biblioteca de E / S de Haskell (putStrLn y así sucesivamente), esto es lo que hará la biblioteca. En las versiones modernas de Haskell, preguntará cuidadosamente a Windows cuál es la página de códigos actual y generará las cadenas con la codificación adecuada. Hay dos problemas con este enfoque:

Uno no es un showstopper, pero es molesto. Como se mencionó anteriormente, la codificación predeterminada casi nunca codificará los caracteres que desea: usted es el usuario que necesita cambiar a una codificación que sí lo hace. Por lo tanto su usuario necesitachcp cp65001 antes de ejecutar su programa (puede resultarle desagradable forzar a sus usuarios a hacer esto). O necesitas unirte aSetConsoleCP y haga el equivalente dentro de su programa (y luego usehSetEncoding para que las bibliotecas de Haskell envíen la salida utilizando la nueva codificación), lo que significa que debe envolver la parte relevante de las bibliotecas de win32 para que sean visibles a Haskell.Mucho más en serio, hay unaerror en las ventanas (resolución: no arreglaré) lo que conduce a unerror en Haskell lo que significa que si ha seleccionado cualquier página de códigos como cp65001 que pueda cubrir todo Unicode, las rutinas de E / S de Haskell funcionarán mal y fallarán. Tan esencialmente,incluso si tú (o tu usuario) configuras la codificación correctamente para alguna codificación que cubra todos los maravillosos caracteres de Unicode, y luego 'haz todo bien' al decirle a Haskell que emita cosas usando esa codificación, aún pierdes.

El error mencionado anteriormente aún no está resuelto y aparece como de baja prioridad; la conclusión básica es que la Opción A (en mi clasificación anterior) no es viable y se debe cambiar a la Opción B para obtener resultados confiables. No está claro cuál será el plazo para que esto se resuelva, ya que parece un trabajo considerable.

La pregunta es:mientras tanto, ¿alguien puede sugerir una solución para permitir el uso de la E / S de la consola Unicode en Haskell en Windows?

Ver tambien estoentrada de la base de datos de Python bug tracker, lidiando con el mismo problema en Python 3 (solución propuesta, pero aún no aceptada en el código base), yesta respuesta stackoverflow, dando una solución para este problema en Python (basado en 'opción B' en mi clasificación).