我对OCaml编译器有一个问题,我无法自己解释。以下代码将无法编译:
open Postgresql
let get_nodes conn =
ignore (conn#exec "SELECT * FROM node_full")
let () =
let c = new connection () in
ignore (get_nodes c)
它出现以下错误:
File "test.ml", line 8, characters 20-21:
Error: This expression has type Postgresql.connection
but an expression was expected of type < exec : string -> 'a; .. >
Types for method exec are incompatible
(第8行是最后一行)
但是下面的代码编译没有错误(并且在代码的完整版本中按预期工作):
open Postgresql
let get_nodes (conn:connection) =
ignore (conn#exec "SELECT * FROM node_full")
let () =
let c = new connection () in
ignore (get_nodes c)
唯一的区别是我在get_nodes函数中指定了conn参数的类型。
有人了解这里发生了什么吗?这是我第一次自己指定一个类型以使代码工作,我是每天的OCaml用户......
另外,我没有在错误消息中看到为什么涉及的类型不兼容,这里是exec函数的类型:
method exec :
?expect:Postgresql.result_status list ->
?params:string array ->
?binary_params:bool array ->
string -> Postgresql.result
和Postgresql.result中的get_all函数的类型:
method get_all : string array array
新年快乐!
答案 0 :(得分:3)
嗯,nlucaroni已经指出,Optional argument in a method with ocaml已经以更简单的形式回答了这个问题,但这里只是简要介绍了我通过阅读该页面所获得的内容。
您对exec
的来电会为其提供推断类型string -> 'a
。这完全不像Postgresql连接的exec
方法的类型,它有三个可选参数。修复它的一种方法是执行您所做的操作:声明conn
参数的类型。您也可以声明exec
方法的可选参数,可能是这样的:
ignore (
(conn#exec :
?expect: 'a ->
?params: 'b ->
?binary_params: 'c ->
string -> 'd) "SELECT * FROM node_full"
)