Почему «Код не является достаточно общим»? - PullRequest
12 голосов
/ 09 июля 2010

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

«Тест 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)

Ответы [ 2 ]

5 голосов
/ 09 июля 2010

Вот еще одно повторение:

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, так что все в порядке.

0 голосов
/ 09 июля 2010

Я предполагаю, что это потому, что строка имеет сигнатуру (obj -> string), поэтому использование строки само по себе заставляет a иметь тип obj. (F # не делает неявных приведений.)

...