Ocaml 在实现之间绑定记录类型

Ocaml 在实现之间绑定记录类型,ocaml,Ocaml,我被困在如何正确实施这一点上。我有一个文件Mytypes.ml,其中包含本地和远程类型的签名,其中包含密码类型的密钥—一个包含签名和验证功能的记录。我还有另外两个文件Cipher1.ml和Cipher2.ml module Mytypes = struct type local_t type remote_t type cipher_t = { local_create : unit ->

我被困在如何正确实施这一点上。我有一个文件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\u t
remote\u t
声明为抽象类型。由于没有返回这些类型值的函数,因此其他模块无法创建这些类型的值

当然,其他模块不能声明自己想要使用的类型
local\t
remote\t

从您编写代码的方式来看,您可能希望
Mytypes
中的定义是模块类型,而不是模块。您可以这样声明模块类型:

module type Mytypes = sig ... end
那么您可以说其他模块具有这种类型:

module cipher1 : Mytypes = struct ... end

谢谢你的帮助。是的,我不应该通过谈论*.ml然后使用模块显示代码来使事情复杂化。。。抱歉。-更新:谢谢你的帮助。是的,我不应该通过谈论*.ml然后使用模块显示代码来使事情复杂化。。。道歉。我已经按照你的建议做了,并将所有内容都转换为模块类型sig和模块结构,所有内容都可以编译:)我在最初的问题中忽略的唯一一件事是另一种类型,它是本地\u t的列表。我想最好再问一个问题。非常感谢你的帮助。干杯