我有这个代码:
cnf.mli
type literal
type clause
type cnf
type l_diff
val l_compare: literal -> literal -> l_diff
Run Code Online (Sandbox Code Playgroud)
cnf.ml(部分)
type l_diff = Same | Negation | Different
Run Code Online (Sandbox Code Playgroud)
checker.ml(部分)
open Cnf
type solution = (literal * bool) list
let rec solve_literal sol l =
match sol with
| [] -> false
| (hl, b)::rs when (l_compare l hl) = Same -> b
| (hl, b)::rs when (l_compare l hl) = Negation -> not b
| _::rs -> solve_literal rs l
Run Code Online (Sandbox Code Playgroud)
这适用于utop使用:
#mod_use "cnf.ml";;
#use "checker.ml";;
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试编译,checker我会收到以下错误:
编译命令:
ocamlbuild cnf.cma
ocamlbuild checker.cma
Run Code Online (Sandbox Code Playgroud)
错误:
+ /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.
Run Code Online (Sandbox Code Playgroud)
我是否以错误的方式使用变体,或者使用编译器错误?
你也没有以错误的方式在签名中使用抽象类型.当你写作cnf.mli
type l_diff
Run Code Online (Sandbox Code Playgroud)
这将类型声明l_diff为抽象类型,换句话说是一个隐藏内容的黑盒子.
相反,当使用#mod_use "cnf.ml"toplevel本身推断签名并使所有类型声明透明时:
type literal = …
type clause = …
type cnf = …
type l_diff = Same | Negation | Different
val l_compare: literal -> literal -> l_diff
Run Code Online (Sandbox Code Playgroud)
(如果要查看完整的推断签名ocamlbuild cnf.inferred.mli应该有效.)使用此签名,构造函数l_diff是可见的,可以直接构造类型的模式匹配值l_diff.
更一般地说,您的签名cnf.mli过于严格:使用此签名,创建类型值的唯一方法l_diff是调用l_compare.然而,然后不可能观察到该类型的内容.同样,使用cnf.mli您提供的接口,无法创建类型的值literal.
| 归档时间: |
|
| 查看次数: |
78 次 |
| 最近记录: |