caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
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


  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;
as well as URLs for NNTP newsgroup(s).