Почему "Код недостаточно общий"?
Может кто-нибудь объяснить, почему второй пример ниже не будет компилироваться?
'Test 2' дает ошибку FS0670: этот код не является достаточно общим. Переменная типа ^ а не может быть обобщена, потому что она не сможет выйти из ее области. ". Я не понимаю это сообщение об ошибке.
// 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)
Ответы
Ответ 1
Здесь другой репродукция:
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
, что означает, что мы не можем включить правильную версию вызова в string
(или f
в моем воспроизведении). В частности. случай, когда вы повышаете до obj
, мы знаем, что мы хотим встроить версию obj
string
, так что это нормально.
Ответ 2
Я предполагаю это, потому что строка имеет подпись (obj → string), поэтому сама по себе использует строку типа obj. (F # не выполняет неявные приведения.)