2014-02-12 4 views
0

У меня есть список: [('a', 'b', 13), ('c', 'b', 2), ('c', 'd', 4) ]. И я хочу, чтобы удалить элемент ('а', 'б', 13), но я не могу сделать это так:Фильтр с двумя условиями

filter (\(a,b,w) -> a /= 'a' && b /= 'b') theList 

Это также удаляет ('C', 'B', 2) , Я новичок в haskell и не знаю, что вызывает это.

Благодаря

+5

Используйте '||' вместо '&&'. – kosmikus

+0

О, это работает. Но я думал, что это будет другим путем, так как я хочу, чтобы оба «a» и «b» находились в одном кортеже. – hboy

+5

Может быть '(\ (a, b, w) -> not (a == 'a' && b == 'b'))' более понятно. –

ответ

8
filter :: (a -> Bool) -> [a] -> [a] 

Теперь filter удаляет все элементы, для которых функция фильтра не возвращающие True. Давайте посмотрим на ваш фильтр:

(\(a,b,w) -> a /= 'a' && b /= 'b') 

Когда делает этот фильтр обратный True? Она возвращает только True если оба a /= 'a' и b /= 'b' истинны:

 
yourfilter  b == 'b'   b /= 'b' 
    a == 'a'   False    False 
    a /= 'a'   False    True 

Однако, это не то, что вы имели в виду. Вы хотите удалить ('a','b',_), так что ваш фильтр должен работать как

 
followingfilter   b == 'b'   b /= 'b' 
    a == 'a'    False    True 
    a /= 'a'    True    True 

Вы только хотите сохранить значения где a /= 'a'илиb /= 'b', поэтому ваш логический комбинатор должен быть ||:

(\(a, b, _) -> (a /= 'a' || b /= 'b')) 

Однако, мы также можем использовать De Morgan's laws, чтобы написать фильтр для левого верхнего угла (a == 'a' && b == 'b') и свести его на not:

(\(a, b, _) -> not (a == 'a' && b == 'b')) 
+0

Это прояснилось, спасибо! – hboy

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