Reputation: 211
I want to find the max element in a int list.
The idea is to call find_max
only once and let support
do the dirty job.
The function support
returns an int, the first value is 0 then when a new max
is found it's value is saved, added to the result ,the previous max is changed and it's value deducted from the result.
This because :
old_max = x
result = 0 + old_max
A new max is found :
new_max= y
result = result - oldmax + new_max
So I'll save the value of new_max
:
0 + old_max - old_max + new_max = new_max`.
Obviously the code above is explicative, this is my real code :
let find_max random =
let rec support rlist max =
if rlist==[] then 0
else
if (List.hd rlist) > max
then -max + (List.hd rlist) + support (List.tl rlist) (List.hd rlist)
else support (List.tl rlist) max ;;
let return = support random 0 0 ;
!return;;
let a = [1;2;3];
print_string "max element in list is : "
print_int (find_max a);
print_string "\n"
The error is on line 9 !return;;
, syntax error (obviously :/ ) on ;;
Upvotes: 1
Views: 1562
Reputation: 36621
Note that this is an excellent place to use List.fold_left
and the standard library's max
function. No mutable state to worry about and it's tail-recursive.
let find_max lst =
List.fold_left max 0 lst
To understand how this works, take a look at how a left fold is implemented.
let rec fold_left f init lst =
match lst with
| [] -> init
| x::xs -> fold_left f (f init x) xs
If we evaluate find_max []
we get List.fold_left max 0 []
which simply evaluates to 0
as documented in your original question.
If we evaluate find_max [1; 3; 2; 4; 5; 0]
then we'd see a progression like:
find_max [1; 3; 2; 4; 5; 0]
List.fold_left max 0 [1; 3; 2; 4; 5; 0]
List.fold_left max (max 0 1) [3; 2; 4; 5; 0]
List.fold_left max (max 1 3) [2; 4; 5; 0]
List.fold_left max (max 3 2) [4; 5; 0]
List.fold_left max (max 3 4) [5; 0]
List.fold_left max (max 4 5) [0]
List.fold_left max (max 5 0) []
5
Upvotes: 0
Reputation: 18902
There is no construct let ... = ...;
in OCaml, local definition use let .. = ... in ...
. You probably want to avoid using ;;
altogether as a beginner too.
Also, structural equality is =
and not ==
. Similarly, you should never useList.hd
and List.tl
in your code as a beginner. Pattern matching is always the superior option.
Typically, all uses of those functions can be replaced by a simple:
match rlist with
| [] -> 0
| hd :: tl -> ...
which is shorter, clearer, and eliminate any possibility to mishandle the empty list.
Your logic is also unnecessarily complex rather than computing max - initial_value
with
-max + hd + support tl hd
you can compute the maximum directly with
hd
You are then calling support support
with too many argument.
We may want to use let () = ...
when computing effect, rather than using ;;
.
Upvotes: 2