CamlinternalFormatBasics.fmt输入错误

时间:2018-10-13 10:14:32

标签: printf ocaml

我正在通过递归编写循环,但遇到了问题:

let isRectangleIn a b c d =
  if (a > c && b > d) || (a>d && b>c) 
    then 
      "TAK"
    else
      "NIE";;

let rec loop k =
  if k = 0 then 0 else 
  let a = read_int () in
    let b = read_int () in
      let c = read_int () in
        let d = read_int () in
            Printf.printf "%s \n" (isRectangleIn a b c d)
            loop (k-1);;


let i = read_int ();;
let result = loop i;;

编译器说

This expression has type
         ('a -> 'b -> 'c, out_channel, unit, unit, unit, 'a -> 'b -> 'c)
         CamlinternalFormatBasics.fmt
       but an expression was expected of type
         ('a -> 'b -> 'c, out_channel, unit, unit, unit, unit)
         CamlinternalFormatBasics.fmt
       Type 'a -> 'b -> 'c is not compatible with type unit 

但是我不明白我在做什么错。有人可以帮我吗?

1 个答案:

答案 0 :(得分:2)

每当看到显示CamlinternalFormatBasics.fmt的错误时,这意味着都涉及到printf函数。此外,如果格式的第一个参数中有函数类型(此处为'a -> 'b -> 'c),则错误是与格式字符串相比,printf的参数过多。

在您的情况下,格式字符串为"%s \n",它需要一个参数,但是您将其与3个参数一起使用:

Printf.printf "%s \n" (isRectangleIn a b c d) loop (k-1)

(您可能会注意到,在此函数应用程序中以及类型错误消息中的函数类型中,有许多多余的参数。)

这里的根本问题是printf表达式和;之间缺少loop (k-1)

Printf.printf "%s \n" (isRectangleIn a b c d);
loop (k-1)

为避免此类问题,通常建议使用ocp-indent(或ocamlformat)自动对代码进行缩进,并避免欺骗性的缩进。例如,ocp-indent会将您的代码缩进为

Printf.printf "%s \n" (isRectangleIn a b c d)
  loop (k-1);;

证明printfloop的级别不同。