con*_*low 2 ienumerable f# interface
我有一个实现IEnumerable<T>接口的类型,一切正常:
open System
type Bar() =
interface Collections.IEnumerable with
member x.GetEnumerator () = null
interface Collections.Generic.IEnumerable<int> with
member x.GetEnumerator () = null
Run Code Online (Sandbox Code Playgroud)
但是如果类型IEnumerable通过基类型继承接口实现,则会出错:
open System
type Foo() =
interface Collections.IEnumerable with
member x.GetEnumerator () = null
type Bar() =
inherit Foo()
interface Collections.Generic.IEnumerable<int> with
member x.GetEnumerator () = null
Run Code Online (Sandbox Code Playgroud)
上面的代码产生类型推断错误:
The member 'GetEnumerator<'a0 when 'a0 : null> : unit -> 'a0 when 'a0 : null' does not have the correct type to override any given virtual method
The member 'GetEnumerator<'a0 when 'a0 : null> : unit -> 'a0 when 'a0 : null' does not have the correct number of method type parameters. The required signature is 'GetEnumerator : unit -> Collections.Generic.IEnumerator<int>'.
我做错了什么或者这是一个F#编译错误?
Microsoft (R) F# 2.0 Interactive build 4.0.30319.1
更新更多规范示例:
type IFoo = abstract Bar : obj list
type IFoo<'a> = abstract Bar : 'a list
inherit IFoo
/* ok */
type Foo = interface IFoo with member x.Bar = []
interface IFoo<Foo> with member x.Bar = []
/* fail */
type FooBase = interface IFoo with member x.Bar = []
type FooDerived = interface IFoo<Foo> with member x.Bar = [] // <---
inherit FooBase
/*
error FS0017: The member 'get_Bar : unit -> 'a list' does not
have the correct type to override any given virtual method.
*/
Run Code Online (Sandbox Code Playgroud)
编译器无法从"null"实现中推断出正确的类型.尝试
open System
type Foo() =
interface Collections.IEnumerable with
member x.GetEnumerator () = null
type Bar() =
inherit Foo()
interface Collections.Generic.IEnumerable<int> with
member x.GetEnumerator () : Collections.Generic.IEnumerator<int> = null
Run Code Online (Sandbox Code Playgroud)
更新:
原因是,由类型实现的GetEnumerator方法的Bar类型是ambigous,因为IEnumerable<'a>implements/inherits non-generic IEnumerable也指定了(非泛型)GetEnumerator方法.那么,编译器应该如何推断出,如果他获得的所有方法都是null,那么您正在尝试实现哪种方法?因此,在这种情况下我们需要一个类型注释.