When should I write my functions as higher order functions
I've recently started learning F# and come across higher order functions
for simple examples such as the following:
Consider a function that calculates sales by multiplying price p by number
of units sold n.
let sales (p,n) = p * (float n);;
The type of this function is given as
val sales : p:float * n:int -> float
i.e. take a pair of float and int and returns a float.
We can instead write this as a higher order function
let salesHi p n = p * (float n);;
The type of this higher order function is given as
val salesHi : p:float -> n:int -> float
i.e. takes a float and returns a function of int to float.
In simple cases this seems to make no difference
sales (0.99, 100);;
salesHi 0.99 100;;
Both give
val it : float = 99.0
However with the higher order function I can feed in the price for
particular items to get new functions. E.g.
let salesBeer = salesHi 5.99;;
let salesWine = salesHi 14.99;;
Then salesBeer 2 gives 11.98 and salesWine 2 gives 29.98.
Also, I've noticed that built-in operators such as + are defined as higher
order functions, so I can write, for example:
let plus2 = (+) 2;
List.map plus2 [1;3;-1];;
and get
val it : int list = [3; 5; 1]
This seems like a good thing. So when I want to implement a function in an
imperative language that would have taken n > 1 arguments, should I for
example always use higher order function in F# (so long as the arguments
are independent)? Or should I take the simple route and use regular
function with an n-tuple and curry later on if necessary? Or something
else?
How do F# programmers decide when to make a function higher order or use a
regular function with a tuple?
No comments:
Post a Comment