x' let y = f 1 //> val y : -6ren">
gpt4 book ai didi

f# - 返回另一个函数的函数在每次调用返回的函数时执行外部函数的主体

转载 作者:行者123 更新时间:2023-12-05 00:43:13 32 4
gpt4 key购买 nike

这对我来说实际上是非常出乎意料的,但考虑一下 F# 中的这段代码:

let f x =
printfn $"{x}"
fun x' -> x'

let y<'t> = f 1 //> val y<'t> : (obj -> obj)
y 2
//>
//1
//val it: obj = 2

我期望的是,只有当您将 f 1 绑定(bind)到“y”时它才会打印“1”(这会告诉我“f”主体只执行一次)但似乎它执行“f”主体“y”的每一个呼唤。这是与自动循环相关的不可避免的影响,还是我遗漏了一些东西,并且有一种方法可以在每次调用返回的函数时绕过外部函数体执行?

最佳答案

关于这里发生的事情的提示是 't 已被限制为 obj 并且 y 的签名是 (obj -> obj)。这就是 F# 编译器有效地说,“我放弃了,这些没有真正的类型,它就是它是什么”,并发出可以在运行时执行但没有任何真正的类型安全性的东西。

这样做的副作用是,因为它不能将 y “固定”到一个已知的签名,它不能评估 f,所以它只是发出 y 作为对 f 的直接调用,因为您已经通过使用 't 参数化它有效地告诉编译器这很好(最终只是是 obj 或“随便什么”)。

为什么会这样? Value restriction !

我怀疑您已经在 F# Interactive 中逐 block 评估了这一点。定义 let y = f 1 的代码行无法使用更多信息进行编译。您可以通过两种方式做到这一点:

  1. y 与真实类型一起使用,该类型会将其签名固定到您使用它的类型。
  2. 给它一个明确的签名,如 let y: int -> int = f 1 以便将其固定为具体类型。

这就是为什么如果您在 FSI 中执行整个代码段或将其作为程序运行,事情会完全按照您的预期工作:

let f x =
printfn $"{x}"
fun x' -> x'

let y = f 1

y 2
y 3

关于f# - 返回另一个函数的函数在每次调用返回的函数时执行外部函数的主体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70724008/

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