gpt4 book ai didi

f# - 为什么 F# currying "flattens"函数类型?

转载 作者:行者123 更新时间:2023-12-01 22:28:15 26 4
gpt4 key购买 nike

以下函数:

let twoInputs x y =
let sum = x + y
let product a = sum * a
product

具有以下类型:

val twoInputs : x:int -> y:int -> (int -> int)

这是完全合理的,我知道为什么会这样。但是为什么这个功能:

let oneInput = twoInputs 1

是类型 val oneInput : (int -> int -> int) ?

不应该是 int -> (int -> int) 吗?

另外,我认为上面的函数应该符合Associative property ,所以 int -> int -> (int -> int)int -> int -> int -> int 应该没有区别。如果是这样,为什么不直接将后者指定为 twoInputs 的函数类型?

最佳答案

括号表示“FsharpFunc<_> 类型的值”,而没有括号表示“真正的 CLR 方法”。在您的示例中,twoInput被编译为真正的 CLR 方法,但返回类型为 FSharpFunc<_> 的值,因此它的类型。但是你的oneInput被编译为 FSharpFunc<_> 类型的类字段,因此它的类型。

你实际上可以实现相同的效果(即将 true 方法转换为值),即使没有柯里化(Currying),非常简单:

> let twoInputs x y =
> let sum = x + y
> let product a = sum * a
> product

> let twoInputsAgain = twoInputs

val twoInputs : x:int -> y:int -> (int -> int)
val twoInputsAgain : (int -> int -> int -> int)

发生这种情况是因为 CLR 不支持“分配方法”的概念,因此 F# 必须通过声明 twoInputsAgain 来编译它作为 FSharpFunc<_> 类型的字段然后为其分配一个继承自 FSharpFunc<_> 的类的实例并调用 twoInputs什么时候Invoke d.

如果你将它反编译为 C#(我使用 ILSpy),这就是你所看到的:

static $Program()
{
$Program.twoInputsAgain@11 = new Program.twoInputsAgain@11();
}

internal class twoInputsAgain@11 : OptimizedClosures.FSharpFunc<int, int, FSharpFunc<int, int>>
{
public override FSharpFunc<int, int> Invoke(int x, int y)
{
return Program.twoInputs(x, y);
}
}

最后,我想指出的是,这种区别在实践中并不重要,除非你练习一些真正的黑魔法,所以你不应该担心它。

关于f# - 为什么 F# currying "flattens"函数类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30915485/

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