この非常に特定の状況を修正する方法を探しています: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
クロージャーを保持し、1 回の呼び出しのみを必要とします。
更新(トーマス用)
私はあなたが提案したことを試しました。
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
で、私は 1 回閉じてすぐに呼び出せるようにしたいと考えていました。したがって、私が期待している出力は次のようになります。
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()