gpt4 book ai didi

f# - F# 如何将可以将多种不同参数类型带入 IL 的函数编译?

转载 作者:行者123 更新时间:2023-12-04 16:23:49 29 4
gpt4 key购买 nike

我对 F# 几乎一无所知。我什至不知道语法,所以我不能举例。

在评论线程中提到,F# 可以声明可以接受多种可能类型参数的函数,例如字符串或整数。这类似于 C# 中的方法重载:

public void Method(string str) { /* ... */ }
public void Method(int integer) { /* ... */ }

但是,在 CIL 中,您不能声明这种形式的委托(delegate)。每个委托(delegate)都必须有一个特定的参数类型列表。然而,由于 F# 中的函数是一等公民,您似乎应该能够传递这样的函数,而将其编译成 CIL 的唯一方法是使用委托(delegate)。

那么 F# 是如何将它编译成 CIL 的呢?

最佳答案

这个问题有点模棱两可,所以我就随便说说 F# 的真实情况。

在 F# 中,方法可以重载,就像 C# 一样。方法总是通过 someObj.MethodName 形式的限定名称访问。或 someType.MethodName .必须有可以在编译时静态解决重载的上下文,就像在 C# 中一样。例子:

type T() =
member this.M(x:int) = ()
member this.M(x:string) = ()
let t = new T()
// these are all ok, just like C#
t.M(3)
t.M("foo")
let f : int -> unit = t.M
let g : string-> unit = t.M
// this fails, just like C#
let h = t.M // A unique overload for method 'M' could not be determined
// based on type information prior to this program point.

在 F# 中,let-bound 函数值不能被重载。所以:
let foo(x:int) = ()
let foo(x:string) = () // Duplicate definition of value 'foo'

这意味着你永远不能有一个“不合格”的标识符 foo这具有重载的意义。每个这样的名称都有一个明确的类型。

最后,可能是引发问题的疯狂案例。 F#可以定义 inline具有“静态成员约束”的函数可以绑定(bind)到例如“所有类型 T 具有名为 Bar 的成员属性”或诸如此类。这种通用性不能编码到 CIL 中。这就是为什么利用这个特性的函数必须是 inline ,以便在每个调用站点,内联生成特定于该调用站点使用的类型的代码。
let inline crazy(x) = x.Qux(3) // elided: type syntax to constrain x to 
// require a Qux member that can take an int
// suppose unrelated types U and V have such a Qux method
let u = new U()
crazy(u) // is expanded here into "u.Qux(3)" and then compiled
let v = new V()
crazy(v) // is expanded here into "v.Qux(3)" and then compiled

所以这些东西都是由编译器处理的,当我们需要生成代码时,再一次,我们已经静态地解析了我们在这个调用点使用的特定类型。 crazy 的“类型”不是可以用 CIL 表示的类型,F# 类型系统只是检查每个调用点以确保满足必要的条件并将代码内联到该调用点,这很像 C++ 模板的工作方式。

(疯狂的东西的主要目的/理由是重载数学运算符。如果没有 inline 功能, + 运算符,例如,作为一个 let-bound 函数类型,可以“仅适用于 int s ” 或“仅适用于 float s”或诸如此类。某些 ML 风格(F# 是 OCaml 的亲戚)就是这样做的,例如 + 运算符仅适用于 int s,以及一个单独的运算符,通常名为 +. ,适用于 float s。而在 F# 中, + 是在 F# 库中定义的 inline 函数,适用于具有 + 运算符成员或任何原始数字类型的任何类型。内联还可以具有一些潜在的运行时性能优势,这对一些数学/计算领域也很有吸引力。)

关于f# - F# 如何将可以将多种不同参数类型带入 IL 的函数编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3757126/

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