由于单元导致F#接口继承失败 [英] F# interface inheritance failure due to unit
问题描述
有人知道为什么它无法编译吗?
Does anyone know why this fails to compile?
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
推荐答案
在F#语言中,这看起来像是一个令人讨厌的极端情况,但是我不确定它是否符合设计限制或是否存在错误.编译器.如果是出于设计限制,则错误消息应显示为该错误消息(因为当前,它没有多大意义).
This looks like a nasty corner-case in the F# language, but I'm not sure if it qualifies as a by-design limitation or a bug in the compiler. If it is by design limitation, then the error message should say that (because currently, it doesn't make much sense).
无论如何,问题在于F#编译器不会生成在IL中实际包含unit
类型的代码.它用void
(当用作返回类型时)或空的参数列表(当用作方法或函数参数时)替换它.
Anyway, the problem is that the F# compiler doesn't generate code that actually contains the unit
type in the IL. It replaces it with void
(when used as a return type) or with empty argument list (when used as a method or function argument).
这意味着在MyClass
类型中,编译器决定将MyFun
成员编译为采用string
并返回void
的方法(但是您不能将void
用作泛型类型参数,因此这是行不通的).原则上,在这种情况下,编译器可以使用实际的unit
类型(因为这是使其正常工作的唯一方法),但这可能会在其他地方造成其他不一致之处.
This means that in the MyClass
type, the compiler decides to compile the MyFun
member as a method that takes string
and returns void
(but you cannot use void
as a generic type argument, so this just doesn't work). In principle, the compiler could use the actual unit
type in this case (because that's the only way to get it working), but that would probably create other inconsistencies elsewhere.
我认为,创建MyUnit
的技巧是解决问题的完美方法.甚至核心F#库在实现的某些地方(在异步工作流中)都使用类似MyUnit
的东西来处理unit
的某些限制(及其编译方式).
Your trick with creating MyUnit
is, I think, a perfectly fine way to solve the problem. Even the core F# library uses something like MyUnit
in some places of the implementation (in asynchronous workflows) to deal with some limitations of unit
(and the way it is compiled).
这篇关于由于单元导致F#接口继承失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!