5

経由でリンクされた関数に引数を渡したい状況がありますCompose。引数でカリーできることはわかっていますが、結果の関数をそれよりも柔軟にしたいと思います。問題を示す簡単なテスト ケースを次に示します。

> library(functional)
> f <- function(x, scale) x^2*scale
> g <- function(y, shift) sqrt(y)+shift
> h <- Compose(f,g)
> h(1)
Error in x^2 * scale : 'scale' is missing
> h(1, scale=1, shift=0)
Error in Reduce(function(x, f) f(x), fs, ...) : 
  unused argument(s) (scale = 1, shift = 0)

Compose結果の関数が呼び出されたときに引数を許可できるよう にする方法はありますか? ?Composeおそらく素敵なキーボードへのエレジーとしてのことを除けば、あまり役に立ちません。

4

1 に答える 1

6

関数合成はコンピュータ サイエンスで定式化されるため、すべての関数は 1 つの引数しか持ちません。関数もこれCompositionを前提としています。Currying はこれを回避する典型的な方法です。もう 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
于 2012-08-06T17:49:19.707 に答える