我一直纠结于如何正确实现这一点。我有一个文件Mytypes.ml,它包含本地和远程类型的签名,其中包含密码类型的密钥——一个包含签名和验证功能的记录。我有另外两个文件Cipher1.ml和Cipher2.ml
module Mytypes = struct
type local_t
type remote_t
type cipher_t = {
local_create : unit -> local_t;
local_sign : local_t -> Cstruct.t -> Cstruct.t;
remote_create : Cstruct.t -> remote_t;
remote_validate : remote_t -> Cstruct.t -> bool;
}
type key_sets = {
mutable locals : local_t list;
mutable remotes : remote_t list;
mutable ciphers : cipher_t list;
}
end
module Cipher1 = struct
open Mytypes
type local_t = {
secretkey : Cstruct.t;
}
type remote_t = {
publickey : Cstruct.t;
}
let c1_local_create () = {secretkey = Cstruct.create 321}
let c1_local_sign local data () = Cstruct.create 21
let c1_remote_create public_key_data = {publickey = Cstruct.create 123}
let c1_remote_validate remote data = true
let create () = {
local_create = c1_local_create;
local_sign = c1_local_sign;
remote_create = c1_remote_create;
remote_validate = c1_remote_validate;
}
end
module Cipher2 = struct
open Mytypes
type local_t = {
ekey1 : Cstruct.t;
}
type remote_t = {
ekey2 : Cstruct.t;
}
let c2_local_create () = {ekey1 = Cstruct.create 321}
let c2_local_sign local data () = Cstruct.create 12
let c2_remote_create public_key_data = {ekey1 = Cstruct.create 123}
let c2_remote_validate remote data = true
let create () = {
local_create = c2_local_create;
local_sign = c2_local_sign;
remote_create = c2_remote_create;
remote_validate = c2_remote_validate;
}
end
我经常遇到的错误是:
File "cipher1.ml", line 14, characters 19-34:
Error: This expression has type unit -> local_t
but an expression was expected of type unit -> Mytypes.local_t
Type local_t is not compatible with type Mytypes.local_t
ocamlmklib returned with exit code 2
- 第14行为:local_create=c1_local_create
有人能提出一条可能的前进道路吗?
这还不完全清楚,但我假设您的示例代码表示三个名为mytypes.ml
、cipher1.ml
和cipher2.ml
的文件。
首先要注意的是,当您说open Mtypes
时,您正在使文件mtypes.ml
的顶级名称可用。但该文件中只有一个顶级名称Mytypes
。
OCaml在文件的最外层免费为您提供了一个模块,因此很少有文件只包含一个模块。对于cipher1.ml
和cipher2.ml
也是如此。
接下来需要注意的是,Mytypes
模块将local_t
和remote_t
声明为抽象类型。由于没有返回这些类型值的函数,因此其他模块无法创建这些类型的值。
其他模块可以声明他们想要使用的类型local_t
和remote_t
的自己版本,这当然不是的情况。
根据您编写代码的方式,您可能希望Mytypes
中的定义是模块类型,而不是模块。您可以声明这样的模块类型:
module type Mytypes = sig ... end
然后你可以说其他模块有这种类型:
module cipher1 : Mytypes = struct ... end