caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Nick Betteridge <lists.nick.betteridge@gmail.com>
To: Runhang Li <runhang@posteo.net>
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 16:02:10 +0000	[thread overview]
Message-ID: <569D0C82.5070505@gmail.com> (raw)
In-Reply-To: <90FAD129-B205-45BE-8D92-9D3AF1D388CE@posteo.net>

Hi,

Really grateful for help on this and thanks for taking time to write
back. Octachron has just emailed me to suggest swapping two lines to
make sure the type system knows that the existential type local_t inside
cm1 and l_k1 are the same (from my original example) - ie:

  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

should be

  let LK (local1', cs1') = l_k1 in
  let module C1' = (val cs1' : Cipher with type local_t = 'a) in
  let signature = C1'.local_sign local1' (Cstruct.create 23) in

Your solution, of course :) , also works - what exactly does the '_' do in:

type _ local_key

- am I right in thinking that this was how the type system figured
everything out?

Thanks again for your time,

Cheers
Nick


On 18/01/16 14:45, Runhang Li wrote:
> 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"

      reply	other threads:[~2016-01-18 16:02 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
2016-01-18 16:02       ` Nick Betteridge [this message]

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=569D0C82.5070505@gmail.com \
    --to=lists.nick.betteridge@gmail.com \
    --cc=caml-list@inria.fr \
    --cc=nicolas.ojeda.bar@lexifi.com \
    --cc=runhang@posteo.net \
    /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).