Возвращая значение из оператора do в haskell охранника

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

Для проверки в списке я использую:

check:: [String] -> Char -> Char
check s c 
    | any (elem c) s = check s (next c)
    | otherwise = do update s c 
                     return c

Но это дает мне ошибку:

Не удалось сопоставить тип "[Char]" с "Char"
Ожидаемый тип: [String] -> [Char] -> Char
Фактический тип: [String] -> [Char] -> [Char]
В блоке 'do' блока: update sc

Моя функция обновления имеет следующую декларацию:

update:: [String] -> Char -> [String]

Есть ли правильный способ выполнить 2 действия в охране? otherwise? Мне нужно вернуть c, чтобы использовать его в другой рекурсивной функции, которая принимает в качестве параметров как Char с и обновил [String] s

Когда у меня были эти функции, возвращающие только c, без обновления списка, там, где нет ошибок:

check:: [String] -> Char -> Char
check s c 
    | any (elem c) s = check s (next c)
    | otherwise = c

Любые советы приветствуются.

Обновление: моя следующая функция:

next :: Char -> Char
next 'Z' = 'A'
next c = chr (ord c + 1)

И для обновления я попробовал:

update:: [String] -> Char -> [String]
update s c = s ++ [[c]]

Дело в том, что позже мне нужно использовать [String] который является результатом обновления, вместе с Char c (результат проверки) в другую функцию. Поэтому после выполнения проверки мне нужно вернуть значение и обновить список с ним.

1 ответ

Решение

Haskell - это функциональный язык, поэтому вы не можете (не должны) думать о мутировании структуры данных, вместо этого функция должна возвращать обновленную версию этой структуры данных и все остальное, что вам нужно. Самый распространенный способ сделать это - вернуть набор нужных вам значений. Вот что вы, вероятно, ищете:

check:: [String] -> Char -> (Char, [String])
check s c 
    | any (elem c) s = check s (next c)
    | otherwise = (c, s ++ [[c]])

Таким образом, вы получите "это" письмо и обновленную версию первоначального списка Strings.

Другие вопросы по тегам