在haskell中,如何根据当前语言环境大写unicode字符

Sav*_*nel 10 unicode haskell

事实证明,对一个角色进行大写是一项复杂的工作.如果退出基本的ASCII字符集,则为字符大写字母和小写字符的规则实际上取决于运行应用程序的语言环境.

作为演示应用程序,我试图用字母'i'(带点)和字母'i'(没有点)来大写.现在,在en_US中,'i'(带点)大写为'I','i'(没有点)不存在(但仍然是大写'I').

但是,如果我切换到土耳其语(tr_TR.UTF-8),'i'(带点)必须大写为'İ'(也带点)和'ı'(没有点)必须大写为'I' (也没有点).小写应该反转这些操作.

i??I --> ??II  (tr_TR.UTF-8)
i??I --> I?II  (en_US.UTF-8)
Run Code Online (Sandbox Code Playgroud)

现在,我可以在C中完美地做到这一点.我怎么能在Haskell中做到这一点?我所做的所有搜索都直接指向Data.Char.toUpper,它不支持区域设置.我没有找到任何以语言环境感知的函数.


这是来自C的代码示例.我在我的Linux机器上运行它.

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <wctype.h>
#include <string.h>
#include <errno.h>

wchar_t latin_small_sharp_s[5] = {0x00df, 0x00df, 0x0053, 0x0053, 0};
wchar_t turkish_is[5] = {0x0069, 0x0130, 0x0131, 0x0049, 0};

char multibyte_turkish_is[7] = {0x69, 0x01, 0x30, 0x01, 0x31, 0x49, 0};

void print_in_locale (const char *locale, const wchar_t *str, const size_t len) {
  wchar_t *dest = calloc(len * 2, sizeof(wchar_t));
  int i;

  if (!setlocale(LC_CTYPE, locale)) {
    fprintf(stderr, "Locale %s failed with error: %s", locale, strerror(errno));
    exit(1);
  }

  for (i = 0; i < len; i++) {
    dest[i] = towupper(str[i]);
  }
  printf("%ls, %ls\n", str, dest);
  free(dest);
}

int main () {
  print_in_locale("de_DE.utf8", latin_small_sharp_s, 5);
  print_in_locale("tr_TR.utf8", turkish_is, 5);
  print_in_locale("de_DE.utf8", turkish_is, 5);
}
Run Code Online (Sandbox Code Playgroud)

如果将其保存到"locale_test.c",则可以在命令行上运行它...

gcc -o locale_test locale_test.c && ./locale_test
Run Code Online (Sandbox Code Playgroud)

Abh*_*kar 13

使用包中的Data.Text.ICU.toUpper功能text-icu.

toUpper :: LocaleName -> Text -> Text

大写字符串中的字符.

Casing依赖于语言环境和上下文敏感.结果可能比原始结果更长或更短.