KLeeT
KLeeT

Reputation: 47

How can I solve the syntax error in loop in Ocaml?

I am learning Ocaml and trying to practice some codes. In this case, I want to produce a code that applies a function repeatedly n times so it goes as f(f(f(....f(f(x)). When n is 0, this will become an identity function. However, when I try the next case, it keeps saying there is a syntax error on the last of my code underlining 'done'

let iter : int * (int -> int) -> (int -> int)
= fun (n, f) -> 
match n with
|0 -> x
|_ -> f c in
        for b = n downto 0 do
          let c = iter x
        done;;

What is wrong with my loop? & I wonder as I intended if it would work when my loop is fixed.

Upvotes: 0

Views: 308

Answers (1)

nimrodm
nimrodm

Reputation: 23789

You have multiple errors in the code. First if you use recursion you should be using let rec. Next, if you recurse you need to call iter with the argument set to n-1 and there is no need for a for loop. If you do use the for loop there is no need to call iter recursively.

The following seems to work:

let rec iter : int * (int -> int) -> (int -> int) =
fun (n, f) ->
  match n with
  | 0 -> f
  | _ -> fun x -> f ( iter (n-1, f) x )

(* let's use the sqr function as an example *)
let sqr = fun x -> x*x

(* iter(0, sqr) = sqr,  iter(1, sqr) = sqr sqr, iter(2, sqr) = sqr sqr sqr *)
(* So f(2) = sqr(sqr(sqr 2)) = 256 *)

let f = iter (2, sqr)

let _ = print_int ( f 2 )

Also note that the iter function returns a new function, so returning a value does not make sense.

For completeness, here's the iterative solution (not recommended) using a for loop

let rec iter : int * (int -> int) -> (int -> int) =
fun (n, f) ->
  match n with
  | 0 -> f
  | _ -> fun x ->
           let result = ref (f x)   in
           for c = n downto 1 do
             result := f !result
           done;
           !result

This version mutates the result variable. result is reference whose value is read using !result and written using result :=.

Disclaimer: I'm not an ocaml expert so the above could probably be improved.

Upvotes: 1

Related Questions