Ocaml 使用依赖项的变量

Ocaml 使用依赖项的变量,ocaml,Ocaml,我有以下代码: cnf.mli type literal type clause type cnf type l_diff val l_compare: literal -> literal -> l_diff cnf.ml(部分) checker.ml(部分) 这在utop中使用: #mod_use "cnf.ml";; #use "checker.ml";; 但是如果我试图编译checker,我会得到以下错误: 编译命令: ocamlbuild cnf.cma ocamlb

我有以下代码:

cnf.mli

type literal
type clause
type cnf
type l_diff

val l_compare: literal -> literal -> l_diff
cnf.ml(部分)

checker.ml(部分)

这在utop中使用:

#mod_use "cnf.ml";;
#use "checker.ml";;
但是如果我试图编译
checker
,我会得到以下错误:

编译命令:

ocamlbuild cnf.cma
ocamlbuild checker.cma
错误:

+ /home/user/.opam/4.05.0/bin/ocamlc.opt -c -o checker.cmo checker.ml
File "checker.ml", line 7, characters 42-46:
Error: Unbound constructor Same
Hint: Did you mean Some?
Command exited with code 2.
Compilation unsuccessful after building 6 targets (2 cached) in 00:00:00.

我是以错误的方式使用变体,还是错误地使用编译器?

也不是,您是以错误的方式在签名中使用抽象类型。当您在
cnf.mli中写入时

type l_diff
这将类型
l_diff
声明为一个抽象类型,换句话说,是一个隐藏内容的黑盒

相反,当使用
#mod_use“cnf.ml”
时,顶级会自行推断签名,并使所有类型声明透明:

type literal = …
type clause = …
type cnf = …
type l_diff = Same | Negation | Different

val l_compare: literal -> literal -> l_diff
(如果您想查看完整的推断签名
ocamlbuild cnf.extensated.mli
应该可以使用。) 通过此签名,
l_diff
的构造函数可见,可以直接构造或模式匹配
l_diff
类型的值

更一般地说,您的签名
cnf.mli
限制性太强:
使用此签名,创建类型为
l_diff
的值的唯一方法是调用
l_compare
。然而,这样就不可能观察到类型的内容。类似地,使用您提供的接口
cnf.mli
,不可能创建
literal
类型的值

两者都不是,您在签名中使用抽象类型的方式是错误的。当您在
cnf.mli中写入时

type l_diff
这将类型
l_diff
声明为一个抽象类型,换句话说,是一个隐藏内容的黑盒

相反,当使用
#mod_use“cnf.ml”
时,顶级会自行推断签名,并使所有类型声明透明:

type literal = …
type clause = …
type cnf = …
type l_diff = Same | Negation | Different

val l_compare: literal -> literal -> l_diff
(如果您想查看完整的推断签名
ocamlbuild cnf.extensated.mli
应该可以使用。) 通过此签名,
l_diff
的构造函数可见,可以直接构造或模式匹配
l_diff
类型的值

更一般地说,您的签名
cnf.mli
限制性太强:
使用此签名,创建类型为
l_diff
的值的唯一方法是调用
l_compare
。然而,这样就不可能观察到类型的内容。类似地,使用您提供的接口
cnf.mli
,不可能创建
literal
类型的值

这意味着l_diff和其他类型必须在cnf.mli中定义。非常感谢,现在它工作了,我不喜欢非常多的复制,但现在还可以^^这意味着l_diff和其他类型必须在cnf.mli中定义。非常感谢,现在它工作了,我不喜欢非常多的复制,但现在还可以^^