Define the function max2 that takes two integers as arguments and returns the largest of them.
I did this: let max2 x y = if x < y then y else x
this I belive is correct
Then define the function max_list that returns the largest of the elements in a nonempty list of integers by calling max2. For the empty list, it should abort with an error message ( raising an exception)
I did this: let list = [3;4] let max_list = if list.IsEmpty then 0 else max2 list.Item(0) list.Item(1)
but this wont work if the list is more then two elements. I dont want to use any object-orientated stuff. What is the correct answer?
A simple recursive solution:
let max2 x y = if x < y then y else x
let max_list list =
let rec loop hi list =
match list with
| h::t -> let hi = max2 h hi
loop hi t
| [] -> hi
match list with
| h::t -> loop h t
| [] -> invalidArg "list" "Empty list"
Test in FSI:
> max_list [3;4;5;1;2;9;0];;
val it : int = 9
For each element in the list, compare it to the previous highest ('hi'). Pass the new highest and the rest of the list into the loop function, until the input list is empty. Then just return 'hi'.
The correct answer is that you should read about recursion with lists.
F# list is built up gradually using empty list []
and cons (::)
constructor. For example,
[3; 4]
is a syntactic sugar for 3::4::[]
. We often use pattern matching on lists in writing recursive functions.
Here is a recursive function following your requirements closely:
let rec max_list xs =
match xs with
// The function aborts with an error message on empty lists
| [] -> invalidArg "xs" "Empty list"
// Return immediately on a singleton list
| [x] -> x
// xs has at least two elements, call max_list
// on the bigger element of the first two ones and the rest of the list
| x1::x2::xs' -> max_list((max2 x1 x2)::xs')
On a side note, there is a built-in generic max function which also works on integers.