Переключить сообщения на языке Haskell

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

Код:

 --upper case
func_upper :: String -> String
func_upper = map (\x-> if x>='a' && x<='z' then 
                    toEnum(fromEnum x-32) else 
                          x)

--Lower case
func_lower :: String -> String
func_lower = map (\x ->if x>='A' && x<='Z' then 
                toEnum (fromEnum x+32) else
                x)

но я не могу объединить эти две функции и сделать одну функцию, которая будет выполнять обе операции. Я практиковал, но не смог. Мой практический код:

    func_ ::String -> String
func_  x = if(x>='a' && x<='z') then toEnum (fromEnum x-32) else 
          if (x>='A' && x<='Z')  then toEnum (fromEnum x+32) else
          x

Пожалуйста, помогите мне решить эту проблему, и ваша помощь будет высоко оценена.

-1
источник поделиться
2 ответа

Во-первых, обратите внимание, что достаточно определить функции только для одиночных символов. Затем вы можете обернуть их на map позже, чтобы работать со строками.

Так что у тебя есть

toUpper :: Char -> Char
toUpper x = if x>='a' && x<='z' then 
                toEnum(fromEnum x-32) else 
                      x

toLower :: Char -> Char
toLower x = if x>='A' && x<='Z' then 
            toEnum (fromEnum x+32) else
            x

... или, поскольку они лучше написаны

toUpper x
 | x>='a' && x<='z'  = toEnum $ fromEnum x - 32
 | otherwise         = x

toLower x
 | x>='A' && x<='Z'  = toEnum $ fromEnum x + 32
 | otherwise         = x

Теперь приятная вещь с этим синтаксисом охранника заключается в том, что вы можете просто добавить дополнительные предложения. Итак, все, что вам нужно сделать, это поставить условные предложения обеих функций в одном. Первый, который выполнит, затем определит, как вычислить результат.

Эквивалентная вещь также может быть выполнена с if, но для этого требуется неловкое гнездование в ветке else.

+3
источник

Вы в основном здесь выполняете map пинги. Вы можете переключить случай, задав отображение, которое для данного символа:

  1. проверяет, является ли он символом верхнего регистра, в случае его возврата, возвращает его нижестоящий эквивалент;
  2. проверьте, является ли он строчным символом, если он есть, верните его верхний регистр; а также
  3. в противном случае вернуть исходный символ.

Мы можем реализовать такую функцию, как:

import Data.Char(isLower, isUpper, toLower, toUpper)

toggleChar :: Char -> Char
toggleChar x | isUpper x = toLower x
             | isLower x = toUpper x
             | otherwise = x

или без использования Data.Char импорта:

toggleChar :: Char -> Char
toggleChar x | 'A' <= x && x <= 'Z' = toEnum (fromEnum x - 32)
             | 'a' <= x && x <= 'z' = toEnum (fromEnum x + 32)
             | otherwise = x

то мы можем реализовать тумблер в течение всей строки по map пинг над toggleChar:

toggleString :: String -> String
toggleString = map toggleChar
+2
источник

Посмотрите другие вопросы по меткам или Задайте вопрос