0

I'm currently attempting to do this problem from the ebook, Haskell School of Music:

Define a function applyAll that, given a list of functions [ f1, f2, ..., fn ] and a value v, returns the result f1 (f2 (...(fn v)...)).

For example: applyAll [simple 2 2, (+3)] 5 ⇒ 20

Currently I have

simple       :: Integer -> Integer -> Integer -> Integer
simple x y z = x * (y + z)

applyAll          :: [(f -> a)] -> a -> a
applyAll [f] v  = foldr (.) v [f]

a = (applyAll [simple 2 2, (+3)] 5)
print a

Which gives me the error:

Couldn't match type `f' with `a0 -> f'
  `f' is a rigid type variable bound by
      the type signature for applyAll :: [f -> a] -> a -> a

Expected type: (f -> a) -> a -> a
  Actual type: (f -> a) -> (a0 -> f) -> a0 -> a
In the first argument of `foldr', namely `(.)'
In the expression: foldr (.) v [f]

I'm assuming it has something to do with the type signature, but nothing I've tried so far has yielded results.

Meta
  • 15
  • 1
  • 5
  • Do you have a question here? – Cody Guldner Jun 10 '13 at 02:56
  • My question was what am I doing wrong here to get this error. I apologize if I worded it incorrectly or if it's an improper question to ask, I'm new to the site and not completely familiar with the posting etiquette. However, jozefg's reply did answer everything I wanted to know about the issue. – Meta Jun 10 '13 at 04:05
  • That is good. Just some food for thought for the future. Make sure your "question" always has a question in it – Cody Guldner Jun 10 '13 at 04:05

1 Answers1

3

The problem here is that the type of . is (b->c) -> (a->b) -> a -> c but our initial value for our fold is not a function. To put this in english, . is function composition, but we want function application. This is easily solved however with ($).

($) f a = f a

so

applyAll :: [(f -> a)] -> a -> a
applyAll [f] v  = foldr ($) v [f]

Next we have a problem with the [f] part. All that does is match a single element list which is probably not what you want.

applyAll fs v = foldr ($) v fs

Now we need to deal with one last part, the type signature. Our function can't take in functions of type f -> a because when we connect them we'll feed a function a value of type a when it expects an f. So the end result is

 applyAll :: [a -> a] -> a -> a
 applyAll fs v = foldr ($) v fs
daniel gratzer
  • 52,833
  • 11
  • 94
  • 134