F# f中的嵌套泛型类型推断#
在下面的代码中,我定义了两个接口,第二个接口将第一个接口作为类型参数。但是,代码给出错误“未定义类型参数“a”F# f中的嵌套泛型类型推断#,f#,F#,在下面的代码中,我定义了两个接口,第二个接口将第一个接口作为类型参数。但是,代码给出错误“未定义类型参数“a” type-IFirst-IFirst您对ISecond的定义不正确:您提到了某个类型'a,但没有定义它。换句话说,ISecond实际上有两个通用参数-'First和'a,但您只定义了其中一个 这将有助于: type ISecond<'a, 'First when 'First :> IFirst<'a>> = abstract First : '
type-IFirst-IFirst您对ISecond
的定义不正确:您提到了某个类型'a
,但没有定义它。换句话说,ISecond
实际上有两个通用参数-'First
和'a
,但您只定义了其中一个
这将有助于:
type ISecond<'a, 'First when 'First :> IFirst<'a>> =
abstract First : 'First
abstract SomeData : 'a
我想你把两个不同的问题混为一谈了。一是:
类型定义的泛型参数都需要显式吗
答案是肯定的。这与类型推断无关,只是类型定义在F#中的工作方式-类型参数'a
仅在IFirst
的参数范围内使用,如果它也是ISecond
的参数
另一个问题是:
在定义子类型时,编译器能否推断超级类型的类型参数
在这里,答案稍微微妙一些。在定义类类型时,答案是指定所有类型参数是一种语法要求。如果您尝试以下方法:
type Second() = interface ISecond<First,_> with ...
但是,在其他情况下,可以推断参数而不会产生问题:
let second() = { new ISecond<_,_> with
member x.SomeData = ""
member x.First = First() }
let second()={new ISecond with
成员x.SomeData=“”
成员x.First=First()}
在这里,您可以看到,当使用对象表达式时,两个参数都可以推断。您需要添加第二个参数-'a
不在范围内,否则(这不是真正的推断,而是类型的结构)。很好,您的解决方案正是我想要的。匿名类型不能用于类型声明有什么具体原因吗?@AmirVakili-这是个好问题,但不幸的是我不知道答案。如果参数是欠约束的,那么在对象表达式的情况下,结果可以是泛型的,但在类型定义中没有意义(因此在特定情况下需要引发错误)。但更一般地说,如果一个功能缺少答案,为什么经常是“没有人实现它”,而不是有某个特定的拦截器。哦,好的。谢谢你的帮助;)
type ISecond<'a, 'First when 'First :> IFirst<'a>> =
abstract First : 'First
abstract SomeData : 'a
type Second () =
interface ISecond<string, First> with
member x.SomeData = ""
member x.First = First()
type Second() = interface ISecond<First,_> with ...
error FS0715: Anonymous type variables are not permitted in this declaration
let second() = { new ISecond<_,_> with
member x.SomeData = ""
member x.First = First() }