2013-10-01 4 views
1

Я ищу способ пройтись по списку, захватив элемент (в том порядке, который он дал, я полагаю), используя его с другой функцией, а затем возвращаясь к этому списку и продолжение операции БЕЗ потери этого элемента из списка.Прогулка по списку, используя элементы, но не теряющие элементы Haskell

В примерах, которые я видел единственный способ сделать это было бы сделать следующее:

counter :: (Eq a1, Num a) => a1 -> [a1] -> a 
counter a []   = 0 
counter a [x]   = if a == x then 1 else 0 
counter a (x:xs)  = if a == x then counter a xs + 1 else counter a xs 


permut :: Eq a => [a] -> [a] -> Bool 
permut [] []   = True 
permut [x] []   = False 

Но это избавляется от элемента х из списка хз когда вызывается снова как в ПЕРЕСТ. Я знаю, что это также служит для завершения рекурсивных вызовов/завершения функции, но мне нужно, чтобы весь список был доступен в моей функции счетчика, чтобы он работал. Я хочу просто пройти через список и сохранить целостность целиком. Это возможно?

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

  1. Они будут иметь одинаковое количество общих элементов (будет осуществлять эту часть позже)

  2. Они будут иметь тот же номер каждого элемента

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

+0

Можете ли вы дать нам прецедент? Ваше описание слишком абстрактно, для меня в любом случае. – Ingo

+0

Просто передайте тот же список в 2 аргумента? И сохраните 2-й вариант без изменений во время рекурсии. – kennytm

+0

@Ingo Я предоставил конкретный прецедент, я пытаюсь работать – ZAX

ответ

3

Совпадение с шаблоном является слишком исчерпывающим, и вам нужно проверить свое состояние для всех элементов. Это должно выглядеть так:

permut [] ys = null ys 
permut xs ys = all condition xs 
    where 
    condition x = .... 

Bonus предложение: Всякий раз, когда это случается, что это правда, что вы оказываетесь писать

if ..... then True else False 

вы пишете много.

----- Приложение:

Итак, вы нашли all, он делает прогулку по списку (хз в нашем случае), и проверяет, если условие истинно для всех элементов (из хза в нашем дело). Например:

all even [1,2,3] 

короткий способ сказать:

even 1 && even 2 && even 3 

Таким образом, в вашем где положении у вас есть condition, и он имеет доступ к исходному хзу и спискам Ю.С., и это называется для каждого элемента из xs. Следовательно, все, что вам нужно проверить, - это если аргумент x из condition встречается столько же раз в xs и ys. Для этого у вас уже есть counter, так что это будет один лайнер.

+0

Я догадываюсь, что я все еще смущен ... Получаю, что у меня будет полный список xs и ys для вызова счетчика, но как я могу вообще «ходить» по списку с помощью предложения where? Боковое замечание, не могли бы вы объяснить использование null и все в вашей функции - я их никогда не видел – ZAX

+0

Я думаю, что я нашел все и null соответствующим образом. Имеет смысл, но сердце моей проблемы все еще распространено, что идет по списку. Условие получит весь список xs, и я могу передать ему весь список ys, но как я могу начать ходить по списку. Для счетчика требуется один элемент, а затем весь список. Если я напишу условие x = counter x ys, он будет иметь оба списка полностью не только один элемент – ZAX

+0

Я добавил больше объяснений. – Ingo

Смежные вопросы