Элегантное определение многих значений функций в haskell - PullRequest
2 голосов
/ 19 апреля 2020

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

yell :: Char -> Char
yell 'a' = 'A'
yell 'b' = 'B'
...
yell 'z' = 'Z'
yell ch = ch

Какой лучший способ сделать это? Я могу составить список пар соответствующих входов и выходов через zip ['a'..'z'] ['A'..'Z'], но я не уверен, как превратить это в определение yell.

Я знаю, что lookup является чем-то вроде вариант, но тогда я должен futz с Maybe, и мне интересно, есть ли что-нибудь еще более элементарное доступным.

1 Ответ

5 голосов
/ 19 апреля 2020

Вы можете использовать защиту и использовать toUpper :: Char -> Char, модуля Data.Char , например:

import Data.Char(toUpper)

yell :: Char -> Char
yell c
    | 'a' <= c && c <= 'z' = toUpper c
    | otherwise = c

для символов ASCII, верхний регистр просто маскирует шестой бит (с маской 0010 0000). Таким образом, toUpper эквивалентно chr . (~0x20 .&.) . ord для указанного диапазона c.

Однако существуют другие символы, которые имеют заглавные буквы, например символы с диакритическими знаками (&#xE0;&#xE1;&#xE2;&#xE3;&#xE4;&#xE5;&#xE6;&#xE7;&#xE8;&#xE9;&#xEA;&#xEB;&#xEC;&#xED;&hellip;), греческие символы (* 1020) *), символы полной ширины (&#xFF41;&#xFF42;&#xFF43;&#xFF44;&#xFF45;&#xFF46;&#xFF47;&#xFF48;&hellip;) и др. c. Все они конвертируются с помощью toUpper и не могут (все) конвертироваться с помощью этого трюка.

Вы можете выполнить поиск с помощью структуры поиска, например, `

import Data.HashMap.Strict(HashMap, fromList)
import qualified Data.HashMap.Strict as HM

items :: HashMap Char Char
items = fromList (zip ['a' .. 'z'] ['A' .. 'Z'])

yell :: Char -> Char
yell c
    | Just y <- HM.lookup c items = y
    | otherwise = c
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...