stumped
stumped

Reputation: 3293

Trouble with printing a string in OCaml

The code compiles without the print statement. However with the print statement I get the error on that line that Error: This expression has type unit but an expression was expected of type int. I've also tried print_string numDigits

let rec rev_int num =
  if num / 10 == 0 then
    num
  else
    let temp = num mod 10 in
    let numDigits = string_of_int num in
    Printf.printf "%s" numDigits

    let num = (num - temp) / 10 in
    temp * (10 * String.length(numDigits)) + rev_int num;;

Upvotes: 1

Views: 1996

Answers (2)

Chris
Chris

Reputation: 36451

To add further illustration for anyone looking at this from the future, OCaml doesn't really care about whitespace. Your code parses as:

let rec rev_int num =
  if num / 10 == 0 then
    num
  else
    let temp = num mod 10 in
    let numDigits = string_of_int num in
    Printf.printf "%s" numDigits

let num = (num - temp) / 10 in
temp * (10 * String.length(numDigits)) + rev_int num

Two things are wrong here.

Firstly, Printf.printf "%s" numDigits returns unit while the other branch of your conditional returns int. This is not going to compile and gives you a type error.

Secondly, if this were a complete program, the following would not be a valid toplevel definition.

let num = (num - temp) / 10 in
temp * (10 * String.length(numDigits)) + rev_int num

As hinted in the existing answer, you likely wanted to use a ; to have a side-effect in the form of the print, and then return that value.

let rec rev_int num =
  if num / 10 == 0 then
    num
  else
    let temp = num mod 10 in
    let numDigits = string_of_int num in
    Printf.printf "%s" numDigits;
    let num = (num - temp) / 10 in
    temp * (10 * String.length(numDigits)) + rev_int num

Alternatively, you can bind the side-effect-causing expression to ().

let rec rev_int num =
  if num / 10 == 0 then
    num
  else
    let temp = num mod 10 in
    let numDigits = string_of_int num in
    let () = Printf.printf "%s" numDigits in
    let num = (num - temp) / 10 in
    temp * (10 * String.length(numDigits)) + rev_int num

As a final note, you have some unnecessary parentheses and Printf.printf "%s" is just print_string (as you seem aware).

let rec rev_int num =
  if num / 10 == 0 then
    num
  else
    let temp = num mod 10 in
    let numDigits = string_of_int num in
    let () = print_string numDigits in
    let num = (num - temp) / 10 in
    temp * 10 * String.length numDigits + rev_int num

Upvotes: 0

mookid
mookid

Reputation: 1172

There is a semicolon missing at the end of the Printf line.

An alternative os the start this line with let () = and end it with in.

Upvotes: 3

Related Questions