Кто-либо может объяснить, почему второй пример ниже не скомпилирует?
'Протестируйте 2', дает "ошибке FS0670: Этот код не является достаточно общим. Переменная типа ^a не могла быть обобщена, потому что она выйдет из своего объема".. Мне не удается понять это сообщение об ошибке.
// Test 1
type test1<'a> = | A of 'a
with
override t.ToString() =
match t with
| A a -> a.ToString()
// Test 2
type test2<'a> = | A of 'a
with
override t.ToString() =
match t with
| A a -> string a
// Test 3
type test3<'a> = | A of 'a
with
override t.ToString() =
match t with
| A a -> string (a :> obj)
Вот еще одно повторение:
let inline f< ^T>(x:^T) = box x
type test4<'a> = | A of 'a
with
member t.M() =
match t with
| A a -> f a
string
- встроенная функция, которая использует ограничения статического типа, и диагностика ошибок для таких функций иногда бывает плохой. Я не совсем понимаю само диагностическое сообщение, но дело в том, что на месте вызова мы не знаем общий тип 'a
, что означает, что мы не можем встроить правильную версию вызов строка
(или f
в моем репро). Например, в В случае, когда вы выполняете преобразование до obj
, мы знаем, что хотим встроить obj
версию строки
, так что это нормально.
Я полагаю, это потому, что строка имеет сигнатуру (obj -> string), поэтому использование строки само по себе заставляет a иметь тип obj. (F # не выполняет неявное приведение типов.)