Micheal Ross
Micheal Ross

Reputation: 211

Max int in list ocaml

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

Answers (2)

Chris
Chris

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

octachron
octachron

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

Related Questions