I stumbled upon an interesting problem when attempting to figure out a way to nicely and elegantly encode tags for data in a modular fashion.
First, we may want to approach the problem in an elementary fashion:
module type TAG = sig
type 'a t
type data
val tag : data -> 'a t
end
let tagme (type a b)
(module Tag : TAG with type data = a)
(item : a) : b Tag.t =
(Tag.tag item : b Tag.t)
It is obvious that it won’t work, because we’ll be attempting to return an existentially typed value. Now, how may we hide this existential type?
Btw, I also don’t see a way to refer to the _ Tag.t
type if I was referencing it from the type definition after the function itself, before the arguments. Could this limitation be overcome in general?
Consider the following monstrosity as an attempt to find a solution:
module type TAG = sig
type row
type 'a tag constraint 'a = row
type t
type data
val tag : data -> t
end
let tagme: type a b.
(module TAG with type data = a and type t = b) -> a -> b =
fun (module Tag) (item : a) ->
Tag.tag item
module Int_tag :
TAG with type data = int =
struct
type row (* supposed to represent 'a variable in tag type *)
type 'a tag = [> `Int of int ] as 'a
type t
type data = int
let tag item = `Int item
end
The goal is to obtain a polymorphic variant value from tagme
. On my first attempt, I wanted to return values from tagme
typed with non-zero arity types within the module TAG
, but it wasn’t possible to express 'a t
in the module type specification. Thus, I tried to approach by returning abstract types. Now, I cannot construct the specific modules.
Does this problem have a solution? Something more general? Am I overlooking a known method? Am I overlooking something obvious?
I wonder, if trying to use something from the Higher_kinded
library would actually help? My slight concern with that approach is that when I need modules in a more efficient implementation, I may be introducing an extra layer of wrapper values (though it appears that the Higher_kinded
specifically uses %identity
, and only changes types).