Racket: Символы

Любой текст в Racket представлен типом string, который представляет собой список фиксированной длины, состоящий из символов — значений типа char.

И вот тут придётся сразу же предупредить: в русском языке слова "character" (если речь идёт о части строки) и "symbol" имеют один и тот же перевод — "символ". Вот только в Racket и других языках семейства lisp есть отдельная сущность symbol и именно её принято называть "символом". Поэтому далее в тексте вы будете встречать либо "строковый символ" либо имя типа, то есть "char". Так будет проще избежать подмены понятий.

Итак, строки состоят из строковых символов. Как же выглядят эти символы сами по себе в виде литералов? Когда речь идёт о печатных символах (printable characters), то любой из оных можно представить в виде символов (ага, опять синоним!) "#\" плюс самого желаемого символа:

(displayln #\a) ; => a
(displayln #\1) ; => 1
(displayln #\,) ; => ,
(displayln #\)) ; => )
(displayln #\\) ; => \
(displayln #\#) ; => #

Как видите, нет проблем с закрывающими скобками и самими # и \ — любой печатный символ может быть закодирован таким образом.

Но как же указать в виде литерала пробел, табуляцию, или перевод строки? Для символа "пробела" ("space") и большинства управляющих символов (control characters) можно указать их имя после #\:

#\space   ; это пробел
#\newline ; a это — перевод строки

Кроме вышеперечисленных способов любой из символов Unicode можно указать, используя его код в десятичном или шестнадцатеричном представлении:

(displayln #\λ)                  ; => λ
(displayln (integer->char 955))  ; => λ
(displayln #\u3BB)               ; => λ
(displayln #\n)                  ; => n
(displayln #\110)                ; => n

Здесь функция integer->char преобразует десятичное число в строковый символ с кодом 955 (греческая буква "лямбда"). 3BB это те же 955 только в шестнадцатеричной форме. 110 — десятичный код ASCII-символа "n".

А вот #\955 использовать не получится: десятичным числом можно задавать только коды в диапазоне 0..255, то есть символы таблицы ASCII. Но символы Unicode повсеместно принято указывать в шестнадцатеричном виде, поэтому данное ограничение не вызывает больших неудобств.

В дополнение к integer->char Racket предоставляет и функцию char->integer, которая вычисляет десятичный код символа. Такие функции преобразования одного типа в другой можно встретить очень часто и во многих случаях функции идут подобными парами.

Задание

Реализуйте две функции, next-char и prev-char, которые вычисляют для символа-аргумента следующий и предыдущий символы (с точки зрения десятичного кода).


Нашли ошибку? Есть что добавить? Пулреквесты приветствуются https://github.com/hexlet-basics
Если вы столкнулись с трудностями и не знаете, что делать, задайте вопрос в нашем большом и дружном сообществе