Ocaml错误Printf.printf

时间:2018-03-11 12:57:53

标签: functional-programming ocaml

let main() = 
let base = read_int () in
let num = read_int () in
if num = reverse num && (is_base base num) = true then Printf.printf "YES"
else if is_base base num = false then Printf.printf "ERROR" 
else Printf.printf"NO" 

此表达式的类型为

     ('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 

我已阅读文档,但目前仍不清楚printf如何在Ocaml中运行。 它适用于顶层。也许有些图书馆遗失了?

1 个答案:

答案 0 :(得分:5)

很有可能代码的下一行是

main ()

或类似的顶级表达式,这是您错误的真正来源。需要通过;;

引入Toplevel表达式
;; main ()

另一个成语是写作

let () = main ()

避免在所有

中引入顶级表达式

现在,你为什么会遇到如此复杂的类型错误?答案很有趣,源于类型检测器从左到右的偏见和printf的灵活性。当我们写作时,一切都开始了:

 Printf.printf "ERROR" main ()

这里,Printf.printf的类型是('a, out_channel, unit) format -> 'a,这意味着:

  • 'a:printf采用格式字符串加上格式所需的参数

  • out_channel:它写在out_channel

  • unit:最终,它返回单位。

但是,在键入函数应用程序时, Printf.printf "Error" main (),类型检查器看到Printf.printf应用于三个参数,因此推断类型'a可以扩展为'b -> 'c -> 'd。但是,类型检查器会查看格式参数"ERROR": ('e, 'f, 'e) format的类型,因此它推断格式的返回类型应为'b -> 'c -> 'd。但这与Printf.printf需要单位作为返回类型的事实相矛盾,导致您的类型错误(经过一些简化):

 ('a -> 'b -> 'c, out_channel,'a -> 'b -> 'c) format
 but an expression was expected of type
 ('a -> 'b -> 'c, out_channel, unit) format
 Type 'a -> 'b -> 'c is not compatible with type unit