Я ищу способ исправить эту очень определенную ситуацию: у меня есть функция-фабрика toF
, которая принимает функциональный параметр g
и на его основе создает результирующую функцию f
Невозможно создать общее частичное применение функции в 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
в закрытии и требует только одного вызова.
UPDATE (для 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
UPDATE 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()
Я не понимаю, как это работает: 'let fx = toF id x' не должно работать, поскольку в' toF id x' есть 2 аргумента, тогда как объявленный 'toF' получает только один параметр' g'. Я имею в виду, что x просто игнорируется или что? –
'let fx =' определяет функцию (которая возвращает функцию, принимающую другой аргумент), а 'let f =' определяет значение (которое фактически является функцией из двух аргументов) –
Это действительно просто синтаксическое условие - оно имеет быть функцией (принимая хотя бы некоторый аргумент) –