#haskell #recursion
Вопрос:
Определите
listCheck :: [[Char]] -gt; [[Char]] -gt; Bool
функция, которая определяет, содержит ли список слов первого аргумента слово, которое также находится в списке второго аргумента. Мы можем предположить, что оба списка содержат только строчные буквы. Если хотя бы один из аргументов является пустым списком, то вернитесь
False
.Например:
listCheck ["hey", "hello", "hi"] ["whatsup", "hi"] == True
listCheck ["hey", "hello", "hi"] ["whatsup"] == False
До сих пор я пытался:
listCheck [] _ = False listCheck _ [] = False listCheck (x:xs) [y] | x == y = True | otherwise = listCheck (xs) [y]
Что делает то, чего я ожидал. Он проверяет только первый элемент второго аргумента (он всегда возвращает правильное значение, если во втором списке есть только один элемент, так что, по крайней мере, я понял это правильно). Я не знаю, как реализовать рекурсию для остальных элементов второго списка.
Комментарии:
1. это не параметры, а аргументы. параметры-это переменные, аргументы-значения.
Ответ №1:
listCheck :: [[Char]] -gt; [[Char]] -gt; Bool listCheck [] _ = False listCheck (x:xs) ys = go x ys || listCheck xs ys where go _ [] = False go x (y:ys) | x == y = True | otherwise = go x ys
Мы используем вспомогательную функцию go
для сравнения одного элемента из одного списка со всеми элементами из другого списка. Если элемент x
не найден в списке ys
, мы пробуем остальные элементы xs
ys
. ||
гарантирует, что функция вернется, как только будет найдено совпадение, без проверки остальных. Наконец, если xs
он исчерпан, мы можем быть уверены, что совпадения нет, и вернуться False
.
Комментарии:
1. Спасибо вам за подробный ответ! Еще один вопрос: В этом контексте
||
означаетor
или похоже наbreak
утверждение в C ?2.
||
является логическим или, которое выполняет RHS только в том случае, если LHS принимает значение False (например, короткое замыкание). Если LHS принимает значение True, он просто возвращает значение True без учета RHS. Кроме того, AFAIK,||
это также логическое короткое замыкание или в C .3. Я понимаю, спасибо вам за помощь.
4. Вы можете использовать тот же
||
трюк вgo
;go x (y:ys) = x == y || go x ys
. Вы также можете использовать существующие функции;listCheck xs ys = any (`elem` ys) xs
. Для повышения эффективности используйте aSet
, как вlistCheck xs ys = any (`S.member` S.fromList ys) xs
.5. @DanielWagner это ответ. 🙂