Reputation: 39
I want to write a function with input is a List of string, and output is a string. For example : List :
3 11 12
15 13 14 15
Output:
(assert
(and (= (+ x11 x12) 3)
(= (+ x13 x14 x15) 15)
))
The code I wrote:
let print data =
printf "(assert \n(and ";
List.iter (fun l ->
let str = "(=(+" in
str ^ "x" ^(String.concat "x" (List.tl l)) ^ ")" ^ (List.hd l) ^ ")\n";
printf str;
) data;
printf "))";
;;
But it didn't work. When compiling, it showed error
Please help me to fix it. Thank you very much
Upvotes: 0
Views: 194
Reputation: 9030
I see three problems.
Printf
moduleprintf
is used without open Printf
. Maybe it is done somewhere else, since apparently you did not paste the whole code. Learn to ask good questions.
printf
printf str
is not well-typed in OCaml. This is pretty confusing for newcomers. OCaml's printf
tries to mimic C's printf behaviour and for this purpose its typing is a little strange. To tell it in very short but a bit inaccurately, the rule is:
printf
must take its format string argument in constant form. Or you are in trouble.
In your code, printf "(assert \n(and "
and printf "))"
is ok since they get string constants, but printf str
is not. It is a variable.
The easy fix is to use print_string
instead of printf
:
print_string str
should work. printf
is tricky but I think I should not go further here. If you want to know more, there are several QAs about OCaml's printf
typing in SO, for example: OCaml Printf.sprintf
Assume that the above typing issue of printf
is fixed by replacing it by print_string
.
We still get a warning "Warning 10: this expression should have type unit." around the string concatenation str ^ "x" ^..
where the questioner tried modifying str
, but this is wrong.
First, note that this expression does not modify the contents of str
. It creates a new string by concatenating str
and other strings. This new string is not used and just discarded in the code, this is why we get the warning. str
is unchanged and therefore the output would be different from what it would be. Warning 10 is a pretty good indication of this sort of bugs and therefore you should not ignore it.
If you want to print the new string you have to give it to print_string
(was printf
in the original code) You should write:
let str' = str ^ "x" ^(String.concat "x" (List.tl l)) ^ ")" ^ (List.hd l) ^ ")\n" in
print_string str'
or, just
print_string (str ^ "x" ^(String.concat "x" (List.tl l)) ^ ")" ^ (List.hd l) ^ ")\n")
Upvotes: 1