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