From: Runhang Li <runhang@posteo.net>
To: Nick Betteridge <lists.nick.betteridge@gmail.com>
Cc: Nicolas Ojeda Bar <nicolas.ojeda.bar@lexifi.com>, caml-list@inria.fr
Subject: Re: [Caml-list] Referencing a functor type
Date: Mon, 18 Jan 2016 09:45:34 -0500 [thread overview]
Message-ID: <90FAD129-B205-45BE-8D92-9D3AF1D388CE@posteo.net> (raw)
In-Reply-To: <569C9915.4060707@gmail.com>
Hi, Nick
Here is my attempt that fixes existential problem. I used heterogeneous list. I am not sure what specific thing you want to do with cipher_module list and local_key list, but feel free to ask me any problem about what you want to do with the list. Also, I used Obj.magic because I don’t know what your implementation about Cipher is, and using Obj.magic does not matter here.
module Cstruct = struct
type t = string
let create n = Obj.magic ()
end
module type Cipher = sig
type local_t
type remote_t
val local_create : unit -> local_t
val local_sign : local_t -> Cstruct.t -> Cstruct.t
val remote_create : Cstruct.t -> remote_t
val remote_validate : remote_t -> Cstruct.t -> bool
end
module MMMake_cipher (Cipher_impl : Cipher) = struct
type local_t = Cipher_impl.local_t
type remote_t = Cipher_impl.remote_t
let local_create = Cipher_impl.local_create
let local_sign = Cipher_impl.local_sign
let remote_create = Cipher_impl.remote_create
let remote_validate = Cipher_impl.remote_validate
end
type _ local_key =
LK : 'a * (module Cipher with type local_t = 'a) -> 'a local_key
type local_key_list =
| KNil : local_key_list
| KCons : 'a local_key * local_key_list -> local_key_list
type _ cipher_module =
CM : (module Cipher with type local_t = 'a) -> 'a cipher_module
type cipher_module_list =
| MNil : cipher_module_list
| MCons : 'a cipher_module * cipher_module_list -> cipher_module_list
type self_t = {
mutable modules : cipher_module_list;
mutable locals : local_key_list
}
module Cipher1 : Cipher = struct
type local_t
type remote_t
let local_create = fun _ -> Obj.magic ()
let local_sign = fun _ _ -> Obj.magic ()
let remote_create = fun _ -> Obj.magic ()
let remote_validate = fun _ _ -> Obj.magic ()
end
module Cipher2 : Cipher = struct
type local_t
type remote_t
let local_create = fun _ -> Obj.magic ()
let local_sign = fun _ _ -> Obj.magic ()
let remote_create = fun _ -> Obj.magic ()
let remote_validate = fun _ _ -> Obj.magic ()
end
module C1x = MMMake_cipher(Cipher1)
module C2x = MMMake_cipher(Cipher2)
let () =
let cs1 = (module C1x : Cipher with type local_t = Cipher1.local_t) in
let cs2 = (module C2x : Cipher with type local_t = Cipher2.local_t) in
let module C1 = (val cs1 : Cipher with type local_t = Cipher1.local_t) in
let module C2 = (val cs2 : Cipher with type local_t = Cipher2.local_t) in
let local1 = C1.local_create () in
let local2 = C2.local_create () in
let l_k1 = LK (local1, cs1) in
let l_k2 = LK (local2, cs2) in
let cm1 = CM (cs1) in
let cm2 = CM (cs2) in
ignore (C1.local_sign local1 (Cstruct.create 23));
let self = {
modules = MCons (cm1, MCons(cm2, MNil));
locals = KCons (l_k1, KCons(l_k2, KNil));
} in
let CM cs1' = cm1 in
let module C1' = (val cs1' : Cipher with type local_t = 'a) in
let LK (local1', cs1') = l_k1 in
let signature = C1'.local_sign local1' (Cstruct.create 23) in
Printf.printf "OK"
> On Jan 18, 2016, at 2:49 AM, Nick Betteridge <lists.nick.betteridge@gmail.com> wrote:
>
> Hi Nicolas, everyone,
>
> I'm having problems in reconstituting the variables - I'm pretty sure I
> need to do some form of 'casting'. As a recap, I've re-written
> everything below with a simple use-case - forming the GADTs works perfectly:
>
>
> module type Cipher = sig
>
> type local_t
> type remote_t
>
> val local_create : unit -> local_t
> val local_sign : local_t -> Cstruct.t -> Cstruct.t
> val remote_create : Cstruct.t -> remote_t
> val remote_validate : remote_t -> Cstruct.t -> bool
>
> end
>
> module Make_cipher :
>
> functor (Cipher_impl : Cipher) ->
> sig
> type local_t = Cipher_impl.local_t
> type remote_t = Cipher_impl.remote_t
> val local_create : unit -> local_t
> val local_sign : local_t -> Cstruct.t -> Cstruct.t
> val remote_create : Cstruct.t -> remote_t
> val remote_validate : remote_t -> Cstruct.t -> bool
> end
>
> type local_key = LK : 'a * (module Cipher with type local_t = 'a) ->
> local_key
> type cipher_module = CM : (module Cipher with type local_t = 'a) ->
> cipher_module
>
> type self_t =
> {
> mutable modules : cipher_module list;
> mutable locals : local_key list
> }
>
>
>
> module C1x = Make_cipher (Cipher1)
> module C2x = Make_cipher (Cipher2)
>
> let () =
> let cs1 = ( module C1x : Cipher with type local_t = Cipher1.local_t) in
> let cs2 = ( module C2x : Cipher with type local_t = Cipher2.local_t) in
> let module C1 = (val cs1 : Cipher with type local_t = Cipher1.local_t) in
> let module C2 = (val cs2 : Cipher with type local_t = Cipher2.local_t) in
> let local1 = C1.local_create () in
> let local2 = C2.local_create () in
> let l_k1 = LK (local1, cs1) in
> let l_k2 = LK (local2, cs2) in
> let cm1 = CM (cs1) in
> let cm2 = CM (cs2) in
> let cslist = [cm1;cm2] in
> ignore (C1.local_sign local1 (Cstruct.create 23));
> let self = {
> modules = [cm1;cm2];
> locals = [l_k1;l_k2];
> } in
> let CM cs1' = cm1 in
> let module C1' = (val cs1' : Cipher with type local_t = 'a) in
> let LK (local1', cs1') = l_k1 in
> let signature = C1'.local_sign local1' (Cstruct.create 23) in
> Printf.printf "OK"
>
>
> An error is given for 'let signature = ....'
> Error: This expression has type a#1 but an expression was expected of type
> C1'.local_t = a#0
>
> I've spent quite a while trying to figure this out and playing around
> with various permutations and am simply getting nowhere!
>
> Cheers
> Nick
>
> --
> Caml-list mailing list. Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
Kindly,
Runhang
next prev parent reply other threads:[~2016-01-18 14:45 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-14 11:14 Nick Betteridge
2016-01-14 11:24 ` Nicolas Ojeda Bar
2016-01-18 7:49 ` Nick Betteridge
2016-01-18 14:45 ` Runhang Li [this message]
2016-01-18 16:02 ` Nick Betteridge
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=90FAD129-B205-45BE-8D92-9D3AF1D388CE@posteo.net \
--to=runhang@posteo.net \
--cc=caml-list@inria.fr \
--cc=lists.nick.betteridge@gmail.com \
--cc=nicolas.ojeda.bar@lexifi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox