* [Caml-list] Referencing a functor type
@ 2016-01-14 11:14 Nick Betteridge
2016-01-14 11:24 ` Nicolas Ojeda Bar
0 siblings, 1 reply; 5+ messages in thread
From: Nick Betteridge @ 2016-01-14 11:14 UTC (permalink / raw)
To: caml-list
Hi,
I'm trying to create a functor for different type of cipher which have
the same signature. The functor compiles Ok, but I can't work out how to
phrase my self_t to build up a list of local key types. Could anyone
suggest a way forward? Thanks, Nick.
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 self_t =
{
mutable modules : (module Cipher) list;
mutable locals : Cipher_impl.local_t list;
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Referencing a functor type
2016-01-14 11:14 [Caml-list] Referencing a functor type Nick Betteridge
@ 2016-01-14 11:24 ` Nicolas Ojeda Bar
2016-01-18 7:49 ` Nick Betteridge
0 siblings, 1 reply; 5+ messages in thread
From: Nicolas Ojeda Bar @ 2016-01-14 11:24 UTC (permalink / raw)
To: Nick Betteridge; +Cc: caml-list
[-- Attachment #1: Type: text/plain, Size: 1566 bytes --]
Hi Nick,
You can wrap the different key types in an existential:
type local_key = LK : 'a * (module Cipher with type local_t = 'a) -> LK
type self_t = local_key list
Cheers,
Nicolas
On Thu, Jan 14, 2016 at 12:14 PM, Nick Betteridge <
lists.nick.betteridge@gmail.com> wrote:
> Hi,
>
> I'm trying to create a functor for different type of cipher which have
> the same signature. The functor compiles Ok, but I can't work out how to
> phrase my self_t to build up a list of local key types. Could anyone
> suggest a way forward? Thanks, Nick.
>
>
> 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 self_t =
> {
> mutable modules : (module Cipher) list;
> mutable locals : Cipher_impl.local_t list;
> }
>
> --
> 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
>
[-- Attachment #2: Type: text/html, Size: 2553 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Referencing a functor type
2016-01-14 11:24 ` Nicolas Ojeda Bar
@ 2016-01-18 7:49 ` Nick Betteridge
2016-01-18 14:45 ` Runhang Li
0 siblings, 1 reply; 5+ messages in thread
From: Nick Betteridge @ 2016-01-18 7:49 UTC (permalink / raw)
To: Nicolas Ojeda Bar; +Cc: caml-list
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
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Referencing a functor type
2016-01-18 7:49 ` Nick Betteridge
@ 2016-01-18 14:45 ` Runhang Li
2016-01-18 16:02 ` Nick Betteridge
0 siblings, 1 reply; 5+ messages in thread
From: Runhang Li @ 2016-01-18 14:45 UTC (permalink / raw)
To: Nick Betteridge; +Cc: Nicolas Ojeda Bar, caml-list
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
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Referencing a functor type
2016-01-18 14:45 ` Runhang Li
@ 2016-01-18 16:02 ` Nick Betteridge
0 siblings, 0 replies; 5+ messages in thread
From: Nick Betteridge @ 2016-01-18 16:02 UTC (permalink / raw)
To: Runhang Li; +Cc: Nicolas Ojeda Bar, caml-list
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"
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-01-18 16:02 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-14 11:14 [Caml-list] Referencing a functor type 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 is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox