Решите, содержит ли список первого аргумента элементы в списке второго аргумента

#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 . Для повышения эффективности используйте a Set , как в listCheck xs ys = any (`S.member` S.fromList ys) xs .

5. @DanielWagner это ответ. 🙂