В haskell, как я могу загладить символ юникода в отношении текущей локали

Оказывается, что верхняя часть символа - сложный бизнес. Если вы выйдете из базового набора символов ASCII, правила для верхнего и нижнего символов символа на самом деле зависят от языка, в котором работает приложение.

Как демонстрационное приложение, я пытаюсь загладить букву "i" (с точкой) и буквой "i" (без точки). Теперь, в en_US, "i" (с точкой) верхние регистры до "I", а "i" (без точки) не существует (но все же верхние регистры - "I" ).

Но если я переключусь на турецкий (tr_TR.UTF-8), "i" (с точкой) должен иметь верхний регистр в "İ" (также с точкой), а "ı" (без точки) должен иметь верхний регистр "Я" (также без точки). Нижняя регистр должна отменить эти операции.

iİıI --> İİII  (tr_TR.UTF-8)
iİıI --> IİII  (en_US.UTF-8)

Теперь я могу сделать это отлично на 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);
}

Если вы сохранили его на "locale_test.c", вы можете запустить его в командной строке с помощью...

gcc -o locale_test locale_test.c && ./locale_test

Ответ 1

Используйте Data.Text.ICU.toUpper из пакета text-icu.

toUpper :: LocaleName -> Text -> Text

Верхние символы в строке.

Корпус зависит от языка и зависит от контекста. Результатом может быть длиннее или короче оригинала.