Это не полный ответ, но он предоставляет немного больше информации и одно возможное решение или обходной путь.
Можно получить последнюю строку для компиляции, добавив явное приведение к определенному комбинированному типу:
let res =
Result.flatMap(
Specific1.res :> Result.t(string, [`Specific1Error | `Specific2Error]),
_ => (Specific2.res :> Result.t(int, [`Specific1Error | `Specific2Error])));
Здесь они оба приведены к одному и тому же типу, так что мы все в порядке.Что касается того, почему это должно быть ясно, я понимаю, что это должно предотвратить случайные ошибки от неправильного набора конструкторов.Подробнее в этом ответе .
Если бы в type error
была задана нижняя граница, нам не пришлось бы указывать явно, что демонстрирует это:
let error1 : Result.t(int, [> `Error1]) = Result.Error(`Error1);
let error2 : Result.t(int, [> `Error2]) = Result.Error(`Error2);
let res = Result.flatMap(error1, _ => error2);
Но поскольку полиморфные варианты с верхней и нижней границами имеют неявную переменную типа, нам по крайней мере придется изменить type error
на type error('a)
.К сожалению, даже тогда я не уверен, как заставить подпись модуля совпадать с реализациями, так как, например, это:
type error('a) = [> | `Specific1Error] as 'a;
завершается неудачно с
Signature mismatch:
...
Type declarations do not match:
type 'a error = 'a constraint 'a = [> `Specific1Error ]
is not included in
type 'a error
Their constraints differ.
Это также неможно привести к полиморфному типу варианта с нижней границей, и я не уверен, почему это так:
let res =
Result.flatMap(
Specific1.res :> Result.t(string, [> `Specific1Error]),
_ => (Specific2.res :> Result.t(int, [> `Specific2Error])));
завершается с
This has type:
(int, [ `Specific2Error ]) Result.t
But somewhere wanted:
(int, [ `Specific1Error ]) Result.t
These two variant types have no intersection
, что указывает на то, что границы просто игнорируются.
Я достиг пределов своих знаний здесь по нескольким направлениям, но я добавил ocaml к вашему вопросу, поскольку у него есть несколько последователей со значительными знаниями, которые, мы надеемся, могут поставить заключительные частивместе.