Ocaml 为什么可以';编译器是否与此函数类型匹配?

Ocaml 为什么可以';编译器是否与此函数类型匹配?,ocaml,Ocaml,我对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 ex

我对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
唯一的区别是我在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

新年快乐

恩,nlucaroni已经指出,这一点在上一篇文章中得到了更简单的回答,但下面是我通过阅读该页得到的简短描述

您对
exec
的调用为它提供了推断类型
string->'a
。这与Postgresql连接的
exec
方法的类型完全不同,后者有三个可选参数。修复它的一种方法是执行您所做的操作:声明
conn
参数的类型。您也可以只声明
exec
方法的可选参数,可能是这样的:

ignore (
    (conn#exec :
        ?expect: 'a ->
        ?params: 'b ->
        ?binary_params: 'c ->
        string -> 'd) "SELECT * FROM node_full"
 )

可能重复:那么这是一个人必须提供给编译器的最少信息,以便它可以推断类型?我仍然感到惊讶,在我看来,这些类型(带或不带可选参数)是兼容的,编译器应该接受它(参见编译器错误消息)。这有意义吗?我认为关键是类型
?myoption:'a->string->'b
不包含在
string->'b
中。仅仅因为您没有在调用中传递任何可选参数,并不意味着类型可以正常工作。您可以想象一个类型系统,其中您的程序是正确的,但不是在OCaml中。(注:我不是类型理论家,只是一个狂热的实践者。)
ignore (
    (conn#exec :
        ?expect: 'a ->
        ?params: 'b ->
        ?binary_params: 'c ->
        string -> 'd) "SELECT * FROM node_full"
 )