Как объявить универсальную функцию, возвращающую тип, удовлетворяющий множественным ограничениям в F #? - PullRequest
3 голосов
/ 02 декабря 2010

Что я пытаюсь написать:

type A() =
    interface IX with ...
    interface IY with ...

type B() =
    interface IX with ...
    interface IY with ...

let mk t : 'T when 'T :> IX and 'T :> IY =
    match t with
    | Choice1 -> new A()
    | Choice2 -> new B()

Обратите внимание на ограничения типа для возвращаемого типа mk. Хотя он не компилируется, компилятор жалуется, что не может преобразовать A и B в 'T.

Ответы [ 2 ]

7 голосов
/ 02 декабря 2010

Если вы управляете типами A и B, то простейшим решением будет определить

type IXY =
  inherit IX
  inherit IY

, а затем иметь A и B наследовать IXY и mk просто возвращает IXY, а не универсальный тип (который на самом деле не имеет смысла, даже без ограничений).

7 голосов
/ 02 декабря 2010

С ограничением все в порядке, но проблема в том, что нет типа, который бы удовлетворял ограничению и был бы супертипом как 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...