type err = [ .... ]
val tx : t -> f:(unit -> ('a, ([> err ] as 'e)) result) -> ('a, 'e) result
And I would like to make a module type that can be used as a functor that could reasonably wrap different instantiations of this function, all with different err types. But I’m running into trouble expressing it because I can’t seem to define a module type where err is guaranteed to be a polymorphic variant.
Somethign liek this:
module type S = sig
module Db : sig
type err
type t
val tx :
t -> f:(unit -> ('a, ([> err ] as 'e)) result) -> ('a, 'e) result
end
I’m a big user of polymorphic variants for in result monads. I know it has some limitations, and maybe this is one of them, but to me they have have a lot of benefits in terms of code readability.
My point is that such constraints do not belong to the module type (aka the specification). Polymorphic variants are certainly useful in implementations.
As far as I know that’s the best you can do unfortunately. Consequently, this makes it difficult to provide convenience functions and monads around the error handling machinery.
It’s probably the main thing I don’t like about using them for errors but I still do in practice because I like the explicitness of my type signatures.