filterList :: (Eq a) => a -> [(a, b)] -> [(a, b)]
>filterList " foo " [( " foo " , 1) , ( " bar " ,2) , ( " foo " ,3)]
[( " foo " ,1) ,( " foo " ,3)]
I have figured out two ways to solve this problem ,
`first way with list comprehension :` filterList a ((x,y):xs) =[(b,c)|(b,c)<-((x,y):xs),a==b]
second way with recursive function:
filterList2 a []=[]
filterList2 a ((x,y):xs)|a==x = (x,y):filterList2 a xs
|otherwise = filterList2 a xs
but I want to solve it with the folder function, and I am stuck.
filterList a ((x,y):xs) = foldr filter1 a ((x,y):xs)
filter1 b ((x,y):xs)|b==x = (x,y)
|otherwise = filter1 b xs
which is not working.
A little help is really appreciated.
There are both problems with the filterList
and filter1
function. The filterList
function has as pattern:
filterList a ((x, y): xs) = …
but that does not make much sense, the type signature, and type inference will guarantee that it is a list of 2-tuples. Your pattern here will not work for an empty list, but filtering an empty list is likely still necessary. You thus should simplify it to:
filterList a ls = …
the foldr :: (a -> b -> b) -> b -> [a] -> b
function is given three parameters:
But you can not use a
as base case, since that base case also determines the type of the result. The base case is here the empty list. We also need to pass a
to the filter1
function, so we can implement this as:
filterList :: Eq a => a -> [(a, b)] -> [(a, b)]
filterList a ls = foldr (filter1 a) [] ls
Your filter1
function works on a list, but that is not how a foldr
function works. The function you pass to foldr
will be given an element, and the result of folding the rest of the list. Your function thus looks like:
filter1 :: Eq a => a -> (a, b) -> [(a, b)] -> [(a, b)]
filter1 a (x, y) rs = …
Here a
is the element we have passed we have to look for, (x, y)
is the 2-tuple we are "folding in", and rs
is the result of folding the rest of the list. So this is a list that is already filtered.
I leave implementing filter1
as an exercise.