Merlin
Merlin

Reputation: 97

OCaml - Printing recursive fatorial function return value not working

I have this code:

let n = read_int()
let rec fact n = if n=0 then 1 else n*fact(n-1)
let () = Printf.printf "%d factorial is %d.\n" n fact(n)

I compile and then the compiler says:

File "fat.ml", line 3, characters 23-46:
Error: This expression has type
         ('a -> 'b, out_channel, unit, unit, unit, 'a -> 'b)
         CamlinternalFormatBasics.fmt
       but an expression was expected of type
         ('a -> 'b, out_channel, unit, unit, unit, unit)
         CamlinternalFormatBasics.fmt
       Type 'a -> 'b is not compatible with type unit

How can I print the returned value?

Upvotes: 0

Views: 508

Answers (1)

octachron
octachron

Reputation: 18892

The problem is a missing parenthesis around fact n:

let () = Printf.printf "%d factorial is %d.\n" n (fact n)

works.

The reason behind the complicated type error that you got is that the compiler reads

let () = Printf.printf "%d factorial is %d.\n" n fact(n)

as

let () = Printf.printf "%d factorial is %d.\n" n fact n

In other words, for the compiler the function printf is applied to 4 arguments: "%d factorial is %d.\n" ,n, fact and n.

But the format string, let's call it fmt, contains only two %d specifiers. Thus the compiler also knows that there printf fmt should takes two arguments and then returns unit. There is the discrepancy: Printf.printf fmt n fact is expected to returns a function that can be applied to the last argument n but it returns unit. Or in other words,

Type 'a -> 'b is not compatible with type unit

The earlier part of the error

This expression has type ('a -> 'b, out_channel, unit, unit, unit, 'a -> 'b) CamlinternalFormatBasics.fmt but an expression was expected of type ('a -> 'b, out_channel, unit, unit, unit, unit) CamlinternalFormatBasics.fmt

is due to the fact that the type of format string is very flexible, and thus the typechecker only fails when it found out that it is not possible to print the format string and returns unit with the provided arguments.

Upvotes: 3

Related Questions