Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why 'Code is not sufficiently generic'?

Can anyone explain why the second example below won't compile?

'Test 2' gives "error FS0670: This code is not sufficiently generic. The type variable ^a could not be generalized because it would escape its scope.". I fail to understand this error message.

// 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)
like image 556
Johan Kullbom Avatar asked Jul 09 '10 09:07

Johan Kullbom


1 Answers

Here's another repro:

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 is an inline function that uses static type constraints, and the error diagnostics for such functions are sometimes poor. I don't really understand the diagnostic message itself, but the point is, at the call site, we don't know the generic type 'a, which means we can't inline the right version of the call to string (or f in my repro). In e.g. the case where you upcast to obj, we know that we want to inline the obj version of string, so that is ok.

like image 143
Brian Avatar answered Oct 22 '22 11:10

Brian