gpt4 book ai didi

f# - 无法在 F# 中创建函数的通用部分应用程序

转载 作者:行者123 更新时间:2023-12-02 07:33:25 26 4
gpt4 key购买 nike

我正在寻找一种方法来解决这种非常特定的情况:我有一个函数工厂toF,它接受一个函数参数g,并基于它创建一个结果函数 f

let toF g = 
let f x = g x
f
let f = toF id

问题是我得到了一个

error FS0030: Value restriction. The value 'f' has been inferred to have generic type    val f : ('_a -> '_a)    Either make the arguments to 'f' explicit or, if you do not intend for it to be generic, add a type annotation.

我可以添加类型注释(我并不急于这样做)或者我可以像这样重写它:

let f' g x = g x
let f x = f' id x

我不喜欢这样做,因为如果我这样做,那么每次调用 f 时,我都会再次调用 f' 并指定 g一路走来。虽然第一个示例将 g 保留在闭包中并且只需要一次调用。

更新(对于 Tomas)

我已经尝试了你的建议。

let toF g = 
printfn "Creating f using g"
let f x =
printfn "x: %A" x
g x
f
let f x = toF id x

let ``test``() =
1 |> f |> f |> ignore

基本上发生的事情是,每次我调用函数 f 时,它首先调用 toF id 获取一个组合函数,然后才调用该组合函数x

Creating f using g
x: 1
Creating f using g
x: 1

所以本质上,组合是在每次调用 f 时通过随后调用 toF 创建的。但这正是我试图避免的。通过定义 let f = toF id 我希望一次性获得一个闭包然后能够立即调用它。所以我期望的输出是:

Creating f using g
x: 1
x: 1

更新 2

出于同样的原因,以下内容也不起作用:

let toF g = 
printfn "Creating f using g"
let f x =
printfn "x: %A" x
g x
f
let f() = toF id
let fg = f()

最佳答案

你只需要让f成为一个句法函数:

let toF g = 
let f x = g x
f
let f x = toF id x

f 在语法上不是一个函数(带参数)而是一个值时,您会遇到“值限制”错误。我不打算在这里解释它,因为在以前的帖子中已经有很好的信息,例如:Understanding F# Value Restriction Errors

编辑 - 如果你想确保 g 只被调用一次(但仍然希望代码是通用的)那么最简单的方法是添加未使用的 unit 参数(使其成为一个函数),然后调用它一次(确定通用参数)并多次使用结果:

let toF g = 
let f x = g x
f
let f () = toF id

let fg = f ()
fg 1
fg 2

遗憾的是,这是必需的,因为拥有一个通用的函数,但由某些计算返回实际上会在类型系统中创建一个微妙的漏洞 - 这就是“值限制”的原因。

关于f# - 无法在 F# 中创建函数的通用部分应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19572242/

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