F#:不能在接口函数参数中省略泛型类型参数

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

下面给出了我正在尝试做的简化案例。

鉴于此记录类型:

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

我想定义一个带有函数的接口,该函数将忽略属性类型的第二个类型参数,并且仅在第一个类型参数的基础上进行操作。如:

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

这给了我:

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

如果我将类型参数提升为接口的类型,那么编译器会很高兴。这里没问题:

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

我想了解这两种情况的区别,以及为什么我不能在第一种情况下使用通配符。

我认为简短的回答是您可以选择:

  • 明确声明成员的所有类型参数,或
  • 声明 none 成员的类型参数,让编译器改为推断它们

所以第一个 atrName 是非法的,因为你明确声明它采用一个类型参数,而实际上它采用两个。请注意,即使您为第二个类型参数命名,这仍然是非法的:

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

另一方面,第二个atrName是合法的,因为编译器可以推断它只接受一个类型参数,所以它等价于:

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