Reputation: 93
I'm stuck on how to implement this correctly. I have one file, Mytypes.ml, which contains the signature of a local and remote type which contain the keys for the cipher type - a record containing functions for signing and validating. I have two other files Cipher1.ml and 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
The error I always get is:
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
Can anyone suggest a possible way forward?
Upvotes: 2
Views: 59
Reputation: 66803
It's not completely clear, but I'll assume that your example code represents three files named mytypes.ml
, cipher1.ml
and cipher2.ml
.
The first thing to notice is that when you say open Mtypes
, you're making available the top-level names of the file mtypes.ml
. But there's only one top-level name in that file, Mytypes
.
OCaml gives you a module for free at the outermost level of a file, so it's fairly rare to have a file containing just one module. This is true for cipher1.ml
and cipher2.ml
also.
The next thing to notice is that your Mytypes
module is declaring local_t
and remote_t
as abstract types. Since you have no functions returning values of these types, there's no way for another module to create values of these types.
It's certainly not the case that other modules can declare their own versions of the types local_t
and remote_t
that they want to use.
From the way you've written your code, it's possible you want the definitions in Mytypes
to be a module type rather than a module. You can declare a module type like this:
module type Mytypes = sig ... end
Then you can say that other modules have this type:
module cipher1 : Mytypes = struct ... end
Upvotes: 1