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
下面给出了我正在尝试做的简化案例。
鉴于此记录类型:
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