OCaml 中关于字符串修改和 `printf` 的错误

Error around string modification and `printf` in OCaml

我想写一个函数,输入是一个字符串列表,输出是一个字符串。 例如 : 名单:

   3   11 12
    15  13 14 15

输出:

(assert
     (and  (= (+ x11 x12) 3)  
            (= (+ x13 x14 x15) 15)
))

我写的代码:

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 "))";
;;

但是没有用。编译时显示错误

请帮我解决一下。 非常感谢

我看到三个问题。

忘记打开Printf模块

printf不用open Printf。也许它是在其他地方完成的,因为显然您没有粘贴整个代码。学会问好问题。

printf

的打字错误

printf str 在 OCaml 中的类型不正确。这对于新手来说是相当混乱的。 OCaml 的 printf 试图模仿 C 的 printf 行为,为此它的类型有点奇怪。简而言之,但有点不准确,规则是:

printf must take its format string argument in constant form. Or you are in trouble.

在您的代码中,printf "(assert \n(and "printf "))" 是可以的,因为它们获取字符串常量,但 printf str 不是。它是一个变量。

简单的解决方法是使用 print_string 而不是 printf:

print_string str

应该可以。 printf 很棘手,但我认为我不应该在这里走得更远。如果你想了解更多,有几个关于 OCaml 的 printf 输入 SO 的 QA,例如:OCaml Printf.sprintf

错误"string modification"

假设上述 printf 的输入问题已通过替换为 print_string 得到解决。

我们仍然在提问者尝试修改 str 的字符串连接 str ^ "x" ^.. 周围收到警告 "Warning 10: this expression should have type unit.",但这是错误的。

首先,注意这个表达式不会修改str的内容。它通过连接 str 和其他字符串来创建一个新字符串。这个新字符串没有被使用,只是在代码中被丢弃,这就是我们收到警告的原因。 str 未更改,因此输出将与实际情况不同。警告 10 是此类错误的一个很好的指示,因此您不应忽略它。

如果你想打印新的字符串你必须把它给print_string(在原来的代码中是printf)你应该写:

let str' = str ^ "x" ^(String.concat "x" (List.tl l)) ^ ")" ^ (List.hd l) ^ ")\n" in
print_string str'

或者,只是

print_string (str ^ "x" ^(String.concat "x" (List.tl l)) ^ ")" ^ (List.hd l) ^ ")\n")