I am looking for a way to fix this very certain situation: I have a function-factory toF
that takes a function-parameter g
and based on it creates a resulting function f
let toF g =
let f x = g x
f
let f = toF id
The problem is that I get a
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.
I can add type annotations (which I am not eager to do) or alternatively I can rewrite it like this:
let f' g x = g x
let f x = f' id x
I don't like doing it this way because if I do then every time I call f
I am making another call to f'
specifying g
along the way. While the first example keeps g
in the closure and requires just one call.
UPDATE (for Tomas)
I have tried what you suggested.
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
What basically is happening is that every time I make a call to the function f
it first calls toF id
getting a composed function and only then calls that composed function on x
.
Creating f using g
x: 1
Creating f using g
x: 1
So essentially the composition is created on every call to f
via subsequent call to toF
. But this is exactly what I was trying to avoid. By defining let f = toF id
I was hoping to get a closure one sigle time and then be able to call it immediately. So the output I am expecting would be:
Creating f using g
x: 1
x: 1
UPDATE 2
The following doesn't work either for the very same reason:
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()