I have to implement a(n) [a -> b] -> [a] -> [b]
function that has to run the given functions on the second list's respective elements.
For example:
functionList [\x->x 2] [2] == [4]
functionList [\x->x 2, \x->x-2, \x->x*2] [2,3,6] == [4,1,12]
So far, I have this:
functionList f xs = [ f x | x <- f ]
which returns a type matching error I don't know what to do with.
CodePudding user response:
You can use zip :: [a] -> [b] -> [(a,b)]
to simplify the problem. If you wanted to use it directly that'd probably look like a = (map (uncurry ($))) . zip
, but zipWith
is a normal shortcut that you should use.
Another option is to use ZipList
(docs).
import Control.Applicative (ZipList(..))
-- I'm just writing this in the text box; i haven't checked if it parses.
a fs xs = getZipList $ ($) <$> (ZipList fs) <*> (ZipList xs)
ZipList
is probably the worst (most verbose, without a clarity advantage) solution for this very simple situation.
Of course you could also re-implement zip by pattern matching on the lists' structures. I would not expect there to be any advantage to that, but if zip
is new to you then you should take a minute to write out both versions, just for practice/understanding.
a [] _ = []
a _ [] = []
a (f:fs) (x:xs) = ...
CodePudding user response:
A slight improvement over @ShapeOfMatter's excellent answer is:
import Control.Applicative (ZipList(..))
a :: [a -> b] -> [a] -> [b]
a fs xs = getZipList (ZipList fs <*> ZipList xs)