0

I want to define function which simply does

test(n, func) = f ∘ f ∘ f ∘ f ... (n times), and when n is 0, it returns identity function.

That is, test(10, func:x->x+3) 0 becomes 30.

So I wrote down this code...

let rec rec_test (n, func) a = 
    if n == 0 then a
    else rec_test (n-1, func) func(a)

But it gives me this error at line 3.

Error: This expression has type 'a -> 'b
       but an expression was expected of type 'a
       The type variable 'a occurs inside 'a -> 'b

Why can't I use func(a) in line 3, like a variable?

2
  • 2
    Because func a is two variables. Did you mean (func a)? Commented Sep 13, 2019 at 0:16
  • 1
    Also, you do not want to use ==. It works here, but doesn't do what you think it does and when you start using it on more complex types it will create weird bugs you don't understand. You want to use = to test equality between values. Commented Sep 13, 2019 at 12:41

1 Answer 1

1

As @melpomene points out, function call syntax in OCaml works by putting the function next to the argument like this: f x. You can parenthesize the x (or the f) if you like, but it doesn't change the meaning: f (x), (f) (x).

Function calls (known as applications) work left to right, and new arguments are passed as long as they keep showing up next to the previous ones. So a call like this:

f x y z

Is a call to f with three arguments. Similarly, your expression

rec_test (n-1, func) func(a)

is treated something like this:

rec_test  (n-1, func)  (func)  (a)

I.e., it represents a call to rec_test that passes three arguments.

You want the call func a to be processed as a subexpression, so you need to parenthesize it.

You can write it like this:

rec_test (n-1, func) (func a)

This is a call to rec_test that passes two arguments, which is what you want.

Sign up to request clarification or add additional context in comments.

1 Comment

The more common way is also to place the n argument last and not pass arguments as tuples as in: let rec rec_test func a = function 0 -> a | n -> rec_test func (func a) (n -1) or with a helper function let test func a n = let rec loop acc = function 0 -> acc | n -> loop (func acc) (n - 1) in loop a

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.