Home > Software design >  Run a list of functions on a list's respective elements
Run a list of functions on a list's respective elements

Time:12-06

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)
  • Related