-- parameters do not need to just be data, they can be other functions, for example function1 :: (Int->Int)->Int->Int function1 f x = f (f x) -- this leads us to 2 very interesting functions that get used a great deal, map and foldl -- I will rewrite map here as function2 function2 :: (a->b)->[a]->[b] function2 f xs = [f x|x<-xs] -- this is interesting because it generalises one of the key uses of a loop in a normal language -- into a short function that can easily be reasoned about. As long as the input function f -- is stable this will be stable -- foldl and foldr generalise the concept of recursion into higher order functions -- the final interesting feature of higher order functions, is that you have already used them -- without realising it -- a definition a->b->c actually means a function that takes something of type a and returns -- another function that maps b's onto c's -- to create a simple function that mapped a's and b's onto c's you would use a tuple (a,b)->c -- however not using tuples is usually better, as it allows a clever trick called sectioning, observe function3 :: [Int]->[Int] function3 xs = map (+1) xs -- this function sections the concept of addition (which takes 2 parameters) and fixes one parameter -- to be a 1. This can be done as much as you like, for example -- function4 :: Int->Int->Float->Char->String -- could be sectioned in the following ways -- (function4 5), giving a function of the defintion (Int->Float->Char->String) -- (function4 5 7 1.0) giving a function with the definition (Char->String)