Подтвердить что ты не робот

Почему "Код недостаточно общий"?

Может кто-нибудь объяснить, почему второй пример ниже не будет компилироваться?

'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)
4b9b3361

Ответ 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 # не выполняет неявные приведения.)