由于单元导致 F# 接口继承失败 [英] F# interface inheritance failure due to unit

查看:20
本文介绍了由于单元导致 F# 接口继承失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人知道为什么编译失败吗?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆