Reputation: 20222
I have the following OCaml code (I know it's probably poorly written and complicated but that's beside the point):
let first (a, _) = a
let second (_, b) = b
let rec findAge limits answer : (int * int) =
if not(first(limits) <= first(answer) &&
first(answer) < second(answer) &&
second(answer) <= second(limits))
then (0, 0)
else
let x = is_valid_answer(answer)
in if x = true
then answer
else
(let y = findAge limits (first(answer) - 1, second(answer))
in if y != (0, 0)
then y
else findAge limits (first(answer), second(answer) - 1));;
I want to put a print statement somewhere in the code to see the call stack of findAge
.
I tried adding a print statement and I changed the code to this:
let rec findAge limits answer : (int * int) =
if not(first(limits) <= first(answer) &&
first(answer) < second(answer) &&
second(answer) <= second(limits))
then (0, 0)
else
(Printf.printf answer and
let x = is_valid_answer(answer)
in if x = true
then answer
else
(let y = findAge limits (first(answer) - 1, second(answer))
in if y != (0, 0)
then y
else findAge limits (first(answer), second(answer) - 1)));;
But I'm getting Error: This '(' might be unmatched
.
I know the error is probably quite obvious since it's a syntax error, so I apologize.
My question is: How can I put some print statements in the code that would help me see the value of the parameters for the recursive call?
Upvotes: 0
Views: 2827
Reputation: 35210
There are no statements in OCaml only expressions. Semicolons, that can be used to separate two expressions that evaluate to a value of type unit, usually bring a lot of confusion, because in conventional languages they are used to separate statements. Since there are no statements in OCaml, the if/else
is also an expression, so if exp1 then exp2; exp3
is actually parsed as (if exp1 then exp2); (exp3)
, not as if exp1 then (exp2;exp3)
, as the if/else
syntax is an expression, not a statement, and ;
has a lower precedence. You can always try to use parenthesis or begin/else
to change the precedence, but for me it is always easier to chain the computations using use let () = exp in ...
syntax, that allows me to foget about counting the nestedness of the parenthesis, e.g.,
if exp then
let () = debug "woa" in
....
result
else
let () = debug "no way" in
...
another_result
Or, picking your example:
open Printf
let rec findAge limits answer : (int * int) =
if not(first(limits) <= first(answer) &&
first(answer) < second(answer) &&
second(answer) <= second(limits))
then (0, 0)
else
let () = printf "here I will print the answer" in
let x = is_valid_answer(answer)
in if x = true
then answer
else
(let y = findAge limits (first(answer) - 1, second(answer))
in if y != (0, 0)
then y
else findAge limits (first(answer), second(answer) - 1));;
Also, a decent OCaml indenter, like ocp-indent
can make your life much easier, as it will indent the code in according to OCaml syntax, so you can see what OCaml is getting, not what you is thinking. For example, this is how it will indent your faulty code (actually showing a place where you broke the syntax):
let rec findAge limits answer : (int * int) =
if not(first(limits) <= first(answer) &&
first(answer) < second(answer) &&
second(answer) <= second(limits))
then (0, 0)
else
(Printf.printf answer and
let x = is_valid_answer(answer)
in if x = true
then answer
else
(let y = findAge limits (first(answer) - 1, second(answer))
in if y != (0, 0)
then y
else findAge limits (first(answer), second(answer) - 1)));
Upvotes: 2
Reputation: 1619
let rec findAge limits answer : (int * int) =
if not(fst(limits) <= fst(answer) &&
fst(answer) < snd(answer) &&
snd(answer) <= snd(limits))
then (0, 0)
else (
Printf.printf "(%d,%d)" (fst answer) (snd answer);
let x = is_valid_answer(answer) in
if x = true
then answer
else (
let y = findAge limits (fst(answer) - 1, snd(answer)) in
if y <> (0, 0)
then y
else findAge limits (fst(answer), snd(answer) - 1)
)
)
;;
Upvotes: 0
Reputation: 66808
You can replace any expression e
with a compound expression like this:
(Printf.printf "%d %d\n" (first answer) (second answer) ; e)
In essence, where you have and
you can use ;
As a completly irrelevant side comment, first
and second
are predefined in OCaml under the names fst
and snd
.
Upvotes: 0