С ограничением все в порядке, но проблема в том, что нет типа, который бы удовлетворял ограничению и был бы супертипом как A
, так и B
.
. Требуется конструкция match
чтобы вернуть один и тот же тип из обеих ветвей, поэтому вам нужно добавить upcast (:>
) к некоторому типу, чтобы преобразование работало для обеих ветвей.Типом может быть либо IX
, либо IY
, но это не будет удовлетворять ограничению.
Это было бы возможно, только если .NET позволил вам написать что-то вроде IX+IY
, что означало бы типкоторый реализует оба интерфейса.Тогда вы также сможете работать со значениями этого типа, например:
let (a:IX+IY) = new A() // This isn't supported
Я думаю, что лучшее решение - просто вернуть кортеж IX * IY
, содержащий два раза один и тот же экземпляр, но представленный как разныетип.Здесь константа, которую вы написали, может быть весьма полезна:
// Type: 'a -> IX * IY when 'a :> IX and 'a :> IY
let asTuple a = (a :> IX, a :> IY)
let mk t =
match t with
| Choice1Of2() -> new A() |> asTuple
| Choice2Of2() -> new B() |> asTuple