|
There
is a nice way to solve this using _folds_. Basically, a fold over a list
is what you would get if you replaced every _:_by some binary operator (such as
_+_) and the end of the list by some constant (such as 0).
In
Haskell one pre-defined fold operator is "foldr" which stands for _fold from the
right_ i.e. associate from the right.
To
find the sum of a list of numbers, you could write:
sum ::
[Int] -> Int
sum =
foldr (+) 0
To
find the length of a list of number, you could use:
length
:: [a] -> Int
length
= foldr ( \ x n -> 1+ n) 0
The
function ( \ x n -> 1 + n) discards its left argument, and returns the right
argument + 1.
so,
your average function could be composed of the sum and length functions defined
like above (I haven't checked for errors).
I know
you are a beginner, but there a very beautiful property of folds that allows you
to combine them. If you define your average using the sum and length
functions, the program is very clear, but it has the drawback of traversing your
list twice. Once to compute the sum and once to compute the length.
Using the _fusion_ property of folds, one could write an average function that
traverses the list just once. For more information on this, there is a
very good paper by Graham Hutton _A tutorial on the universality and
expressiveness of fold_ which probably can be found on the web or in a
University Library in the Journal of Functional Programming.
Enjoy.
--Peter Douglass
|
