Ok I had tried something like that and found a way to coerce the types to match but it turns out I had another problem causing the make function to return a closed poly var constraint rather than open.
I was using reazen/relude’s NonEmpty.List module to contain a list of “errs” and I had to implement my own non-empty list type to get it to work.
module type NonEmptyList = {
type container('a) = list('a); /* If this line is abstract (as in just "type container('a);" it causes problems */
type t('a) = option(container('a));
/* ... */
}
Furthermore my
D.t('a, 'b)
type expanded to
result(('a, array('b)), list('b));
And if array was used to contain 'b, it caused the poly vars to always infer as closed.
So if any of the above were true (if I used array type to contain the polyvars instead of list), it would cause
let make: string => D.t(t, [> errs]);
/* D.t('a, [ `Specific1Error ]) */
Whereas if I changed to list type, removed the abstract type in the interface to explicitly define list, then the type would be inferred as
/* D.t('a, [> `Specific1Error ]) */
Then that lets me do the workaround given in this answer: https://stackoverflow.com/a/53930341