Reputation: 97
I have a problem whereby I have a list of tuples ("Song Name", "Artist Name", SalesFig)
and I have to filter out a tuple within that list that contain a specific Song Name and Artist Name and return all the other tuples within that list.
Below is my code:
testData = [("No Lie", "Sean Paul feat. Dua Lipa", 100),
("Yes Lie", "Sean Paul feat. Dua Lipa", 10),
("Fear & Delight", "The Correspondents", 120),
("Hello", "Adelle", 4)]
filterTrack :: String -> String -> [(String, String, Int)] -> [(String, String, Int)]
filterTrack songName artistName items = filter p items
where p (song', artist', _) = songName /= song' && artistName /= artist'
Now the problem I am having with the codee is that when I want to filter one of the two songs within the list and enter say filterTrack "Yes Lie" "Sean Paul feat. Dua Lipa" testData
to remove "Yes Lie"
from, the list, the program removes the other song by the same artist, "No Lie"
, as well.
I am unsure why this is happening as I have an expression which requires the entry to not match with songName and
artistName. I could understand why this is happening if there was an OR
rather than an AND
as it would be true if either one of the conditions were true.
I would have thought using an AND
would make is so it returns every tuple that exactly doesn't match with the Song Name
and the Artist Name
, not just Artist Name
Upvotes: 1
Views: 62
Reputation: 97
Based on hints from @arrowd, changing where p (song', artist', _) = songName /= song' && artistName /= artist'
to where p (song', artist', _) = songName /= song' || artistName /= artist'
solved my issue.
Upvotes: 0
Reputation: 21686
This is your filter function:
p (song', artist', _) = songName /= song' && artistName /= artist'
It is equivalent to this pseudo-code:
NOT sameArtist AND NOT sameSong
Which is, by De Morgans Theorem, equivalent to:
NOT (sameArtist OR sameSong)
Which is not what you want, but explains the behaviour you are seeing.
What you want your filter to be is:
NOT (sameArtist AND sameSong)
Which is written as:
p (song', artist', _) = not (songName == song' && artistName == artist')
Upvotes: 2