Home > Enterprise >  OCaml type error with function application
OCaml type error with function application

Time:02-04

let max2 (x:float) (y:float) :float = 
    if x>=y then x else y;;

let max4 (x:float) (y:float) (a:float) (b:float) :float =
    max2(max2(x, y), max2(a, b));;

Error: This expression has type 'a * 'b but an expression was expected of type float

I was trying to get the max of 4 numbers using a max between 2 numbers function.

CodePudding user response:

The syntax for applying a function f to some arguments arg1 and arg2 is simply:

f arg1 arg2

Notice the complete absence of parenthesis or commas to separate the arguments. If i want let's say to apply another function g to this previous result, i can now put parenthesis around the function expression and the last argument as in:

g (f arg1 arg2)

This is different from what you may be used to in other languages where you put parenthesis after the function name and around the arguments.

Also, the syntax (e1,e2) builds the couple (2-tuple) with e1 as first member and e2 the second.

So max2 (x, y) is the application of the function max2 to a single argument which is a couple. This is different than max2 x y which is what you want.

CodePudding user response:

try this:

 let max2 (x:float) (y:float) :float = 
        if x >= y then x else y;;
    
    let max4 (x:float) (y:float) (a:float) (b:float) :float =
        max2 (max2 x y) (max2 a b);;

the types for max2 and max4 are explicitly specified so the error should be resolved

CodePudding user response:

Addendum to @ghilesZ's answer: local bindings can also be useful.

let max2 (x:float) (y:float) : float = 
  if x >= y then x 
  else y

let max4 (x:float) (y:float) (a:float) (b:float) : float =
  max2 (max2 x y) (max2 a b)

We could write:

let max4 (x:float) (y:float) (a:float) (b:float) : float =
  let m1 = max2 x y in
  let m2 = max2 a b in
  max2 m1 m2

Also, because the types for max2's arguments are explicitly specified, we can elide the return type annotation, and all type annotations on max4 and OCaml will correctly infer the types.

let max2 (x:float) (y:float) = 
  if x >= y then x 
  else y

let max4 x y a b =
  let m1 = max2 x y in
  let m2 = max2 a b in
  max2 m1 m2

You may also wish to generalize this to work on a list of floats, which you could implement max4 in terms of.

let maxA =
  function
  | [] -> failwith "Empty list"
  | h::t -> List.fold_left max2 h t

let max4 x y a b = 
  maxA [x; y; a; b]
  • Related