我正在寻找一种方法来解决这个非常确定的情况:我有一个函数工厂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
在闭包中,只需要一次调用。
更新(托马斯)
我已经尝试过你的建议。
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
获取一个组合函数,然后才调用该组合函数 on 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()