I’m struggling and seeking wisdom. I have the signature
...
val input :
arpv4:('a -> unit Lwt.t) ->
ipv4:('a -> unit Lwt.t) ->
ipv6:('a -> unit Lwt.t) ->
?decap:(Mirage_protocols.Ethernet.proto ->
Cstruct.t -> Mirage_protocols.Ethernet.proto * 'a) ->
t -> Cstruct.t -> unit Lwt.t
If I let 'a be Cstruct.t, I’ve notified of
Values do not match:
val input :
arpv4:(Cstruct.t -> unit Lwt.t) ->
ipv4:(Cstruct.t -> unit Lwt.t) ->
ipv6:(Cstruct.t -> unit Lwt.t) ->
?decap:(Mirage_protocols.Ethernet.proto ->
Cstruct.t -> Mirage_protocols.Ethernet.proto * Cstruct.t) ->
t -> Cstruct.t -> unit Lwt.t
is not included in
val input :
arpv4:('a -> unit Lwt.t) ->
ipv4:('a -> unit Lwt.t) ->
ipv6:('a -> unit Lwt.t) ->
?decap:(Mirage_protocols.Ethernet.proto ->
Cstruct.t -> Mirage_protocols.Ethernet.proto * 'a) ->
t -> Cstruct.t -> unit Lwt.t
I appreciate the response and now understand what I’m doing wrong. My goal is to be generic and defer typing and implementation to the parameter functions. That is, let the parameter functions determine the type. How do I go about this?
That’s hard to say without knowing the implementation. In general I would guess that some part of your code is passing a Cstruct.t to one of arpv4/ipv4/ipv6 and/or using the result of decap as if it contains a Cstruct.t.
Your question does not immediately make a great deal of sense. If you want Cstruct.t to be an abstract type then then have an interface file that makes it so. If you want to pass your functions a number of different possible types and match on them then consider using a variant type. You can make a factory function for first class modules with type deduction using locally abstract types, but that seems well beyond what you have in mind.
By the way, if you want to use modules as a kind of abstract interface that you are going to code to for different types, you can do it with (possibly destructive) sharing constraints. Something like this:
module type Printable = sig
type t
val say : t -> unit
end
module Int_print: Printable with type t := int = struct
let say i = Printf.printf "%d\n" i
end
module String_print: Printable with type t := string = struct
let say s = Printf.printf "%s\n" s
end
let () =
let open Int_print in
say 20 ;
let open String_print in
say "hello"