From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 6772B7F8C9 for ; Mon, 18 Jan 2016 15:45:39 +0100 (CET) IronPort-PHdr: 9a23:QIV9gBwifHS3SwjXCy+O+j09IxM/srCxBDY+r6Qd0OoTIJqq85mqBkHD//Il1AaPBtWFraMawLSM+4nbGkU+or+5+EgYd5JNUxJXwe43pCcHRPC/NEvgMfTxZDY7FskRHHVs/nW8LFQHUJ2mPw6anHS+4HYoFwnlMkItf6KuStCU3pr8ibr60qaQSjsLrQL1Wal1IhSyoFeZnegtqqwmFJwMzADUqGBDYeVcyDAgD1uSmxHh+pX4p8Y7oGx48sgs/M9YUKj8Y79wDfkBVGxnYFYO+dbzuBLfYQyK73oaGiVKw1sbSzTCuTf7VZS5mCbmqudn2SWVMIWiSbEvRS/k6aZgS1nihTsbOiQ4/G7aosN1haNf5hmmokos7ZTTZdSvKfx+d6XSNfcbDT5bQ8BRXipOKpu7dJcCCKwHMPoO/Nq1nEcHsRbrXVrkP+jo0DIdwyKv0A== Authentication-Results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=runhang@posteo.net; spf=Pass smtp.mailfrom=runhang@posteo.net; spf=None smtp.helo=postmaster@mout01.posteo.de Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of runhang@posteo.net) identity=pra; client-ip=185.67.36.65; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="runhang@posteo.net"; x-sender="runhang@posteo.net"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of runhang@posteo.net designates 185.67.36.65 as permitted sender) identity=mailfrom; client-ip=185.67.36.65; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="runhang@posteo.net"; x-sender="runhang@posteo.net"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mout01.posteo.de) identity=helo; client-ip=185.67.36.65; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="runhang@posteo.net"; x-sender="postmaster@mout01.posteo.de"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0AyAQCx+ZxWnEEkQ7lehAxtiFajOZF7GAqFbQKBMzwQAQEBAQEBAQEQAQEBAQEGDQkJIS6CLYIHAQEBAwEBAiAERwsFCwsYAgIJHQICIQcdEgYTEod0AwoMAQmuV4wqAwqDRwEBAQEBAQEDAQEBAQEBAQEBAQEYgQCHZIJwgk+CBoMfLoEbBYYkDIgJiGGFSIUrdIF4gV5Khn6FW4Z/g22DcTmCUoICIDQBhzsBAQE X-IPAS-Result: A0AyAQCx+ZxWnEEkQ7lehAxtiFajOZF7GAqFbQKBMzwQAQEBAQEBAQEQAQEBAQEGDQkJIS6CLYIHAQEBAwEBAiAERwsFCwsYAgIJHQICIQcdEgYTEod0AwoMAQmuV4wqAwqDRwEBAQEBAQEDAQEBAQEBAQEBAQEYgQCHZIJwgk+CBoMfLoEbBYYkDIgJiGGFSIUrdIF4gV5Khn6FW4Z/g22DcTmCUoICIDQBhzsBAQE X-IronPort-AV: E=Sophos;i="5.22,312,1449529200"; d="scan'208";a="197941125" Received: from mout01.posteo.de ([185.67.36.65]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Jan 2016 15:45:38 +0100 Received: from dovecot03.posteo.de (dovecot03.posteo.de [172.16.0.13]) by mout01.posteo.de (Postfix) with ESMTPS id D88F520A93 for ; Mon, 18 Jan 2016 15:45:37 +0100 (CET) Received: from mail.posteo.de (localhost [127.0.0.1]) by dovecot03.posteo.de (Postfix) with ESMTPSA id 3pkbWj0GBBz5vNC; Mon, 18 Jan 2016 15:45:36 +0100 (CET) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 9.2 \(3112\)) From: Runhang Li In-Reply-To: <569C9915.4060707@gmail.com> Date: Mon, 18 Jan 2016 09:45:34 -0500 Cc: Nicolas Ojeda Bar , caml-list@inria.fr Content-Transfer-Encoding: quoted-printable Message-Id: <90FAD129-B205-45BE-8D92-9D3AF1D388CE@posteo.net> References: <569782FC.1020904@gmail.com> <569C9915.4060707@gmail.com> To: Nick Betteridge X-Mailer: Apple Mail (2.3112) X-Validation-by: runhang@posteo.net Subject: Re: [Caml-list] Referencing a functor type Hi, Nick Here is my attempt that fixes existential problem. I used heterogeneous lis= t. 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 wan= t to do with the list. Also, I used Obj.magic because I don=E2=80=99t know = what your implementation about Cipher is, and using Obj.magic does not matt= er here. module Cstruct =3D struct type t =3D string let create n =3D Obj.magic () end module type Cipher =3D 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) =3D struct type local_t =3D Cipher_impl.local_t type remote_t =3D Cipher_impl.remote_t let local_create =3D Cipher_impl.local_create let local_sign =3D Cipher_impl.local_sign let remote_create =3D Cipher_impl.remote_create let remote_validate =3D Cipher_impl.remote_validate end type _ local_key =3D LK : 'a * (module Cipher with type local_t =3D 'a) -> 'a local_key type local_key_list =3D | KNil : local_key_list | KCons : 'a local_key * local_key_list -> local_key_list type _ cipher_module =3D CM : (module Cipher with type local_t =3D 'a) -> 'a cipher_module type cipher_module_list =3D | MNil : cipher_module_list | MCons : 'a cipher_module * cipher_module_list -> cipher_module_list type self_t =3D { mutable modules : cipher_module_list; mutable locals : local_key_list } module Cipher1 : Cipher =3D struct type local_t type remote_t let local_create =3D fun _ -> Obj.magic () let local_sign =3D fun _ _ -> Obj.magic () let remote_create =3D fun _ -> Obj.magic () let remote_validate =3D fun _ _ -> Obj.magic () end module Cipher2 : Cipher =3D struct type local_t type remote_t let local_create =3D fun _ -> Obj.magic () let local_sign =3D fun _ _ -> Obj.magic () let remote_create =3D fun _ -> Obj.magic () let remote_validate =3D fun _ _ -> Obj.magic () end module C1x =3D MMMake_cipher(Cipher1) module C2x =3D MMMake_cipher(Cipher2) let () =3D let cs1 =3D (module C1x : Cipher with type local_t =3D Cipher1.local_t) in let cs2 =3D (module C2x : Cipher with type local_t =3D Cipher2.local_t) in let module C1 =3D (val cs1 : Cipher with type local_t =3D Cipher1.local_t= ) in let module C2 =3D (val cs2 : Cipher with type local_t =3D Cipher2.local_t= ) in let local1 =3D C1.local_create () in let local2 =3D C2.local_create () in let l_k1 =3D LK (local1, cs1) in let l_k2 =3D LK (local2, cs2) in let cm1 =3D CM (cs1) in let cm2 =3D CM (cs2) in ignore (C1.local_sign local1 (Cstruct.create 23)); let self =3D { modules =3D MCons (cm1, MCons(cm2, MNil)); locals =3D KCons (l_k1, KCons(l_k2, KNil)); } in let CM cs1' =3D cm1 in let module C1' =3D (val cs1' : Cipher with type local_t =3D 'a) in let LK (local1', cs1') =3D l_k1 in let signature =3D C1'.local_sign local1' (Cstruct.create 23) in Printf.printf "OK" > On Jan 18, 2016, at 2:49 AM, Nick Betteridge wrote: >=20 > Hi Nicolas, everyone, >=20 > 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 perfect= ly: >=20 >=20 > module type Cipher =3D sig >=20 > type local_t > type remote_t >=20 > 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 >=20 > end >=20 > module Make_cipher : >=20 > functor (Cipher_impl : Cipher) -> > sig > type local_t =3D Cipher_impl.local_t > type remote_t =3D 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 >=20 > type local_key =3D LK : 'a * (module Cipher with type local_t =3D 'a) -> > local_key > type cipher_module =3D CM : (module Cipher with type local_t =3D 'a) -> > cipher_module >=20 > type self_t =3D > { > mutable modules : cipher_module list; > mutable locals : local_key list > } >=20 >=20 >=20 > module C1x =3D Make_cipher (Cipher1) > module C2x =3D Make_cipher (Cipher2) >=20 > let () =3D > let cs1 =3D ( module C1x : Cipher with type local_t =3D Cipher1.local_t)= in > let cs2 =3D ( module C2x : Cipher with type local_t =3D Cipher2.local_t)= in > let module C1 =3D (val cs1 : Cipher with type local_t =3D Cipher1.local_= t) in > let module C2 =3D (val cs2 : Cipher with type local_t =3D Cipher2.local_= t) in > let local1 =3D C1.local_create () in > let local2 =3D C2.local_create () in > let l_k1 =3D LK (local1, cs1) in > let l_k2 =3D LK (local2, cs2) in > let cm1 =3D CM (cs1) in > let cm2 =3D CM (cs2) in > let cslist =3D [cm1;cm2] in > ignore (C1.local_sign local1 (Cstruct.create 23)); > let self =3D { > modules =3D [cm1;cm2]; > locals =3D [l_k1;l_k2]; > } in > let CM cs1' =3D cm1 in > let module C1' =3D (val cs1' : Cipher with type local_t =3D 'a) in > let LK (local1', cs1') =3D l_k1 in > let signature =3D C1'.local_sign local1' (Cstruct.create 23) in > Printf.printf "OK" >=20 >=20 > An error is given for 'let signature =3D ....' > Error: This expression has type a#1 but an expression was expected of type > C1'.local_t =3D a#0 >=20 > I've spent quite a while trying to figure this out and playing around > with various permutations and am simply getting nowhere! >=20 > Cheers > Nick >=20 > --=20 > 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