gpt4 book ai didi

visual-studio-2010 - 如何让 F# 推断通用基类型?

转载 作者:行者123 更新时间:2023-12-04 22:23:41 25 4
gpt4 key购买 nike

考虑一下:

module Module1 =
type A() = class end
type B() = inherit A()
type C() = inherit A()

let f x = if x > 0 then new B() else new C()

最后一行产生关于预期类型 B 的错误,但找到了类型 C。
好的,我可以假装理解:如果有很多,编译器不知道要推断哪个公共(public)基础。

但猜猜怎么了?即使我指定了函数类型,它仍然不起作用:
    let f x : A = if x > 0 then new B() else new C()

现在这给了我两个错误:“A 预期,B 找到”和“A 预期,C 找到”。
怎么回事?为什么它看不到 B 和 C 都可以隐式转换为 A?

是的,我知道我可以使用 upcast ,像这样:
    let f x : A = if x > 0 then upcast new B() else upcast new C()

但你猜怎么着(再次)? upcast仅在存在显式函数类型声明的情况下有效!
换句话说,这:
    let f x = if x > 0 then upcast new B() else upcast new C()

仍然给出错误。

怎么回事?!我真的必须在我的程序中添加 50% 的噪音来帮助编译器吗?
那些关于 F# 代码干净无噪音的炒作是怎么回事?

不知何故,感觉这不可能是真的。
所以问题是:我错过了什么吗?如何使这既紧凑又有效?

最佳答案

正如 Carsten 的链接在某种程度上讨论的那样,类型推断和子类型不能很好地结合在一起。听起来您对 F# 的方法不满意,如果

if b then 
e1
else
e2

被隐含地对待更像
if b then (e1 :> 'a) else (e2 :> 'a)

编译器还根据 'ae1 推断的类型另外推断 e2 是类型层次结构中的最小上限。

这样做在技术上可能是可行的,我无法明确说明为什么 F# 不能以这种方式工作,但这里有一个猜测:如果 if 语句以这种方式运行,那么在 ifelse 分支,因为它们总是可以通过隐式向上转换到 obj 来统一。然而,在实践中,这几乎总是一个程序员错误——你几乎总是希望类型相同(例如,如果我从一个分支返回一个字符,从另一个分支返回一个字符串,我可能打算从两个分支返回字符串,而不是 obj )。通过隐式向上转换,您只会使这些错误的存在更难找到。

此外,在 F# 中处理复杂的继承层次结构相对较少,除非与其他 .NET 代码进行互操作。因此,这在实践中是一个非常小的限制。如果您正在寻找语法上比 upcast 更短的解决方案,您可以尝试 :> _ ,只要有一些限制类型的东西(整体结果上的注释或其中一个分支上的特定转换),它就会起作用.

关于visual-studio-2010 - 如何让 F# 推断通用基类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9893179/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com