由于单位F#接口继承失败

Ste*_*vev 17 f# unit-type

有谁知道为什么这不能编译?

type MyInterface<'input, 'output> = 
    abstract member MyFun: 'input -> 'output

type MyClass() = 
    interface MyInterface<string, unit> with
        member this.MyFun(input: string) = ()
    //fails with error FS0017: The member 'MyFun : string -> unit' does not have the correct type to override the corresponding abstract method.
type MyUnit = MyUnit
type MyClass2() = 
    //success
    interface MyInterface<string, MyUnit> with
        member this.MyFun(input: string) = MyUnit
Run Code Online (Sandbox Code Playgroud)

Tom*_*cek 17

这看起来像是F#语言中令人讨厌的角落,但我不确定它是否符合设计限制或编译器中的错误.如果是设计限制,那么错误消息应该说(因为目前它没有多大意义).

无论如何,问题是F#编译器不生成实际包含unitIL 中的类型的代码.它将其替换为void(当用作返回类型时)或使用空参数列表(当用作方法或函数参数时).

这意味着在MyClass类型中,编译器决定将MyFun成员编译为接受string和返回的方法void(但是您不能将其void用作泛型类型参数,因此这不起作用).原则上,编译器可以unit在这种情况下使用实际类型(因为这是使其工作的唯一方法),但这可能会在其他地方产生其他不一致.

MyUnit我认为,创建的诀窍是解决问题的完美方法.甚至核心F#库也使用类似实现MyUnit的某些地方(在异步工作流程中)来处理unit(以及编译方式)的一些限制.

  • 有趣的是,它将在C#中工作,我可以在F#中使用该函数。可能应该报告为错误。 (2认同)