0

I have to write a function that given a list of keys finds all values associated with these keys in a given association list, where a key can have more then one associated values. Therefore the function has to concatenate the results of the lookups for the individual keys.

Here is my code for lookupOne:

lookupOne :: Int -> [(Int,a)] -> [a]
lookupOne x list = [values | (key,values)<-list, x==key]

Now I have to write the code for lookupAll that will look up for each key of the list and match it to the pair then append the results. I have to follow this:

lookupAll :: [Int] -> [(Int,a)] -> [a]
lookupAll ... = 

So I tried many ways to do this but I just cannot figure this out: How does one extract one element of the keys (because my lookupOne only takes an Int and not [Int]) each time and look it up to the pairs of (key,value). I tried with a map function but it won't work because I don't know how to map a function that uses two arguments (lookupOne) as map apparently just takes one list as its argument. I also can't figure out how to pattern match it because apparently xs doesn't mean that on the next round it will again only extract one element of [keys] Can you please help me comprehend this <3

2 Answers 2

3

There may be more concise and efficient ways to do this, but sticking to your original implementation you could write it like this:

lookupAll :: [Int] -> [(Int,a)] -> [a]
lookupAll xs list = [values | (key,values) <- list, key `elem` xs]
Sign up to request clarification or add additional context in comments.

4 Comments

And any (==key) is also known as elem key ;)
Corrected, I'm not familiar with functions working with list associations, I usually go for containers when I need something like it. Thanks @CarstenSchultz
It was of course correct to begin with, it is only that key `elem` xs reads more nicely.
Sorry, it was a typo. Got it now.
0

You want to use map, that is fine. Now you already realised that you would need a function that takes only one argument, the key, but looupOne takes two. However, the list argument will be the same for every invocation, so we can do the following.

lookupAll :: [Int] -> [(Int,a)] -> [a]
lookupAll xs list = ...
    where f x = lookupOne x list

That f is the kind of function that you need. Now we can do map f xs, however the result will be a list of lists. You can either use concat on the result or look at the definition of concatMap to see how you could use that.

If you like list comprehensions then you can also try

lookupAll xs list = [... | x <- xs, ... <- lookupOne x list, ... <- ...]

I leave it to you (since it looks like homework) to figure out the rest.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.