関数合成はコンピュータ サイエンスで定式化されるため、すべての関数は 1 つの引数しか持ちません。関数もこれComposition
を前提としています。Curry
ing はこれを回避する典型的な方法です。もう 1 つの複雑な点は、追加の名前付き引数を構成プロセスで正しい関数に渡す必要があることです。
いくつかのアプローチを次に示します。
h1 <- function(scale, shift)
Compose(Curry(f,scale), Curry(g,shift))
h1
名前付きパラメータを取り、正しくカリー化されたもので構成された関数を作成します。戻り値は 1 パラメーター関数です。
> h1(scale=1, shift=0)(1)
[1] 1
もう 1 つのアプローチは、実際の関数評価までカリー化 (および構成) を遅らせることです。この場合、元の "Compose" 関数はすべてをセットアップするだけで、実際には構成せず、カリー化し、構成し、評価する関数を返します。
ComposeDelayedCurry <- function(...) {
fs <- list(...)
all.formals <- lapply(fs, formals)
function(...) {
local.args <- list(...)
pos.args <- lapply(all.formals, function(f) {
local.args[names(f)[[-1]]]
})
curried <- lapply(seq_along(fs), function(i) {
do.call(Curry, c(fs[[i]], pos.args[[i]]))
})
do.call(Compose, curried)(..1)
}
}
h2 <- ComposeDelayedCurry(f,g)
これで、呼び出しh2
は評価時にすべての作業を行います。これにはいくつかの仮定があります。1 つは、各関数 (および関数呼び出し) の最初の引数が、構成されているものであることです。2 つ目は、他のすべての引数が名前付き引数であることです。を介して関数に何も渡すことはできません...
。これは、各関数の形式を調べて、各引数がどこに「行く」かを知る必要があるためです。これは、デフォルト値で引数を指定しないことを処理すると思いますが、完全にはわかりません。
> h2(1, scale=1, shift=0)
[1] 1
> h2(3, scale=5, shift=2)
[1] 8.708204
> sqrt(5*(3^2))+2
[1] 8.708204