2
votes

I have a homework on higher order functions in Haskell and I'm having a little trouble getting started.

If I could get some help and explanation on the first question, I'm confident I can finish the rest.

Using higher order functions (map, fold, or filter), and if necessary lambda expressions, write functions f1 and f2 such that f1 (f2 (*) [1,2,3,4]) 5 ~> [5,10,15,20]

f1 = 
f2 = 

I'm thinking I have to use a partially applied map so that [1,2,3,4] becomes [(*1),(*2),(*3),(*4)] ?

2
I'd say you should start with f1 g n = g n and then write f2 such that f2 (+) [1..4] 5 == [5,10,15,20]Ingo
Yes, f2 = map sounds like a good idea.Bergi

2 Answers

2
votes

I'm thinking I have to use a partially evaluated map so that [1,2,3,4] becomes [*1,*2,*3,*4] ??

Your intuition brings you closer to the answer, so that's a good sign

That said, the expression you're given to work with is really weird

f1 (f2 (*) [1,2,3,4]) 5

I would write f1 and f2 as follows

let f1 = \xs n -> map (\f -> f n) xs
    f2 = map
in f1 (f2 (*) [1,2,3,4]) 5
-- [5,10,15,20]
0
votes

If you take f2 = map, you immediately get to the first step that you've come up with:

f2 (*) [1, 2, 3, 4] =
map (*) [1, 2, 3, 4] =
[(1 *), (2 *), (3 *), (4 *)]

Now given this list of multiplier functions, we need

f1 [g1, g2, ..., gn] x =
[g1 x, g2 x, ..., gn x]

since then we can apply it on f2 (*) [1..4] to get

f1 [(1 *), (2 *), (3 *), (4 *)] 5 =
[1 * 5, 2 * 5, 3 * 5, 4 * 5] =
[5, 10, 15, 20]

which is what you're after.

If you look at f1, it looks almost like a map, except the arguments are flipped:

f1 = \gs x -> map h gs

Now we just need to figure out what h is. h needs to be something that takes a function like (2 *) and gives you the result of applying that function to 5; i.e. h = \g -> g 5.

Putting it all together, we get

let f2 = map
    f1 = \gs x -> map (\g -> g x) gs
in f1 (f2 (*) [1, 2, 3, 4]) 5