Reputation: 51
I am trying to create a function in HASKELL that takes a predicate and two lists as arguments and returns a list composed of elements from the second list in those positions where the predicate, when applied to the element in the corresponding positions of the first list, returns True. What I have so far is...
select :: (t -> Bool) -> [t] -> [a] -> [a]
select _ [] = []
select p (x:xs)
| p x = x : select p xs
| otherwise = select p xs
p11tests = [select even [1..26] "abcdefghijklmnopqrstuvwxyz" == "bdfhjlnprtvxz", select (<= 'g') "abcdefghijklmnopqrstuvwxyz" [1..26] == [1,2,3,4,5,6,7]]
p11tests is where I test the function. Not sure what I am doing wrong.
Upvotes: 1
Views: 1138
Reputation: 477318
You are not working with two lists. Your function is in essence a filter
function where you retrieve all items x
in the (first) list that satisfy the predicate p
.
You want to check if the predicate matches for the item of the first list, and in that case yield the item in the second list, so:
select :: (t -> Bool) -> [t] -> [a] -> [a]
select _ [] [] = []
select _ (_:_) [] = []
select _ [] (_:_) = []
select p (x:xs) (y:ys)
| p x = …
| otherwise = …
where I leave filling in …
as an exercise.
You can also work with a combination of zip
, filter
and map
where you first zip
the two items together, then filter items where the first item of the 2-tuples satisifies the predicate, and then you map on the second element. So something like:
select :: (t -> Bool) -> [t] -> [a] -> [a]
select p xs = map snd . filter (p . fst) . zip xs
Upvotes: 1