Понимание встроенных и статически разрешенных параметров типа F #: пример приведения F # - PullRequest
4 голосов
/ 17 ноября 2010

Встроенные функции F # со статически разрешенными общими параметрами кажутся похожими на шаблоны C ++. Однако, в отличие от C ++, вам нужно указать ограничения - как это работает?

Например, я пытаюсь реализовать функцию апскейтинга, но это не сработает:

let inline myUpcast< ^a, ^b  when ^a :> ^b  > (x: ^a) :  ^b =  x

Сообщение об ошибке: error FS0698: Недопустимое ограничение: тип, используемый для ограничения, закрыт, что означает, что ограничение может быть удовлетворено не более чем одним решением.

На самом деле я пытаюсь написать функцию, которая будет приводить последовательности, когда базовые типы могут быть преобразованы (чтобы обойти отсутствие ковариации), но следующее тоже не совсем работает:

let inline upcastseq (xs: seq< ^a >) : seq< ^b > when ^a :> ^b = xs :?> seq< ^b >

, что вызывает следующее предупреждение: предупреждение FS0064: эта конструкция приводит к тому, что код будет менее общим, чем указано в аннотациях типов. Переменная типа 'a ограничена типом' ^ b '. Как и следовало ожидать, на самом деле использование функции не работает, как ожидалось.

Итак, я ищу функцию, которая вызовет ошибку проверки типа, если будет использоваться для преобразования последовательностей ковариантно недопустимым образом (отсюда ограничение общего параметра) - возможна ли такая вещь?

Чуть более широко, каковы ограничения статически разрешенных параметров типов по сравнению с шаблонами C ++?

1 Ответ

4 голосов
/ 17 ноября 2010

Это невозможно, но это не связано с ограничениями статических элементов.Использование обычных общих ограничений одинаково обречено по той же причине:

// doesn't work
let myUpcast<'a, 'b when 'a :> 'b) (x: 'a) : 'b = unbox (box x)

В основном F # не допускает ограничений типа, включающих два разных параметра типа;они всегда должны быть равными.

См. мой ответ на Как ограничить один параметр типа другим для получения дополнительных комментариев.

...