Home > database >  F#: Can't omit generic type parameter in interface function parameter
F#: Can't omit generic type parameter in interface function parameter

Time:11-18

A simplified case of what I'm trying to do is given below.

Given this record type:

type Attribute<'TName,'TOther> =
    {
        Name:'TName
        Data:'TOther
    }

I want to define an interface with a function which will ignore the second type parameter of the Attribute type, and will operate only on the basis of the first type parameter. As in:

type AttributeMapper =
    interface
        abstract member  atrName<'a> :  Attribute<'a, _> -> 'a
    end

This gives me:

 ...: [FS0715] Anonymous type variables are not permitted in this declaration'

If I hoist the type parameter to Interface's type, then the compiler is happy. No problems here:

type AttributeProcessor2<'a> =
    interface
        abstract member  atrName:  Attribute<'a, _> -> 'a
    end
    
let atrMapperInstance2 =
    {new AttributeProcessor2<_> with
        member _.atrName (x:Attribute<string, _>) = x.Name }    

I want to understand the difference between the two cases, and why I'm not allowed to use a wildcard in the first case.

CodePudding user response:

I think the short answer is that you have a choice between:

  • Explicitly declaring all of a member's type parameters, or
  • Declaring none of a member's type parameters, which lets the compiler infer them instead

So the first atrName is illegal because you've explicitly declared it to take one type parameter when it actually takes two. Note that this would still be illegal even if you gave the second type parameter a name:

type AttributeMapper =
    interface
        abstract member  atrName<'a> :  Attribute<'a, 'b> -> 'a   // error FS0039: The type parameter 'b is not defined.
    end

On the other hand, the second atrName is legal, because the compiler can infer that it takes only one type parameter, so it's equivalent to:

type AttributeProcessor2<'a> =
    interface
        abstract member  atrName<'b> :  Attribute<'a, 'b> -> 'a
    end
  • Related