4
votes

I'm trying to teach myself OCaml through Jason Hickey notes and the following exercise got me stumped. Question: Write a function sum that given two integer bounds m,n and a function f computes a summation. I'm trying this:

     let rec sum m n f=
     if m>n then 0
     else if m=n then f n
     else f m + sum n m+1 f

but it doesn't work, producing a type error.

2
Type error _ sum n m_ `Error: This expression has type ('a -> int) -> 'b but an expression was expected of type int'. I already got an answer but I guess if I read this more carefully I had a chance to figure it out myself.Torus

2 Answers

7
votes

You need some parentheses.

let rec sum m n f=
     if m>n then 0
     else if m=n then f n
     else f m + sum n (m+1) f

(Although for readability, I would usually parenthesize the last line as else (f m) + (sum n (m+1) f). ) What's happening without the parentheses is that it's treating it as (f m) + (sum n m) + (1 f) which is producing the error that sum n m doesn't have type int, as it's a partial function application with a more complex type.

As a general rule, when an expression is being passed as an argument to a function, it always needs to be parenthesized. On a related note, if you ever actually wanted to pass the plus function as an argument, you would put it in parentheses (for example: sum m n (+) (although that wouldn't type check in this case, since + expects two numbers)).

6
votes

Function application (binding of function names to their arguments) has the highest precedence in OCaml. So, you need to watch your parentheses. I'm not giving the solution because it might be more fun to figure it out yourself.