.net - 显式类型成员约束中的 "or"

标签 .net generics f# polymorphism constraints

受到FSharpPlusplus函数(相当于mappend)实现的启发,我决定复制该模式并实现一个递增数字的通用函数(使用 LanguagePrimitives 可能会更容易,但这只是一个练习)。

type NumberExtensions =
    static member Increment (x:float) = x + 1.0    
    static member Increment (x:int) = x + 1
    //etc

let inline increment number =
    let inline call (_:^E) (number:^N) = ((^E or ^N) : (static member Increment: ^N -> ^N) number)
    call (Unchecked.defaultof<NumberExtensions>) number //!

let incrementedFloat = increment 100.0
let incrementedInt = increment 200

它按预期工作:

val incrementedFloat : float = 101.0
val incrementedInt : int = 201

不幸的是,我不太明白为什么我们在约束中需要或^N。据我了解,约束条件是:

There's a static method named Increment, which takes an argument of some type (the same type as the number's) and returns another value of the same type. This method must be defined either in ^E or in ^N.

这里我想:我们知道Increment方法将在^E中定义,所以我们可以安全地改变(^E或^N) 改为 ^E。不幸的是,更改导致标有 ! 的行出现以下错误:

A unique overload for method 'Increment' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member NumberExtensions.Increment: x:float->float, static member NumberExtensions.Increment: x:int->int

为什么在约束中添加 或 ^N 可以消除这种歧义?它是否告诉编译器除了方法的可能位置之外的其他信息?

最佳答案

here对此进行了非常好的讨论。 。

一般来说,我们讨论的是如何访问与一系列类型相关的运算符字典,并且以更严格的方式处理用 'a(即质数 a)定义的类型。

一如既往,FSharp source code是一个值得一看的好地方。请参阅:

let inline GenericZero< ^T when ^T : (static member Zero : ^T) > : ^T =

在上面的讨论中,请参阅 Jon Harrop 关于类系统对 Haskell 性能影响的评论。我无法评论 F# 在这方面的 future ,但是,具有显式默认样式会带来某些优势(和权衡)。

在这种情况下,耐心等待这些怪癖,看看默认值是否真的对您有帮助,这可能会很有用。然后弄清楚你可以从这次经历中得出什么结论。不过,这个过程可能需要 6 个多月的时间。当人们固执己见时,也许有充分的理由。有时,如果您提前采取某种做法,很难意识到将会带来哪些好处。到最后,你仍然不必同意。您的情况可能另有要求。

关于.net - 显式类型成员约束中的 "or",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44510166/

相关文章:

F# - JSON 类型提供程序 - 文字字符串

.net - 可移植类库和.NET ConcurrentDictionary

c# - 现有连接被 WCF 中的远程主机强行关闭

java - 编码为泛型类型

c# - 读取大 TXT 文件,内存不足异常

c# - 如何使泛型类成为另一个实例类中的属性?

java - 当枚举被声明为通用参数时获取枚举的 values()

.net - 搜索中的重要数据结构

c# - 从 Azure 应用服务 FTP 到本地服务器上的文件夹

.net - MSBuild 项目与 PowerShell 构建过程