1

次のスキーム コードを Mathematica に変換しようとしています (問題がある場合はバージョン 8)。

(define (((lift g) . fs) . args)
  (apply g
         (map (lambda (f) (apply f args))
              fs)))

次に、次のようなことができます。

(let ((add (lift +))
      (square (lift sqr)))
  ((add (square sin) (square cos)) 42))
; returns 1, since sin^2(42) + cos^2(42) = 1

パーツ(add (square sin) (square cos))は関数を作成しますx -> sin^2(x) + cos^2(x)

とにかく、Mathematica でこれをコーディングしようとしましたが、あまりうまくいかないようです。書きたいことは次のとおりです。

lift[g_] := Function[{fs__}, Function[{args__},
            g @@ Map[(# @@ args)&, fs]]]

私は、それぞれの関数へのすべての引数のリストにバインドしたいfs__と考えています。args__しかし、Mathematica は、 の「パラメータ仕様」はFunction「シンボルまたはシンボルのリスト」であるべきだと文句を言います。()&スタイル無名関数を使用してすべての引数を取得できることはわかってい##ますが、問題は、これらの無名関数を 2 つ入れ子にすると、内部関数内から外部引数にアクセスできなくなることです。

可変アリティ (および名前付き引数) を持つ無名関数を作成するにはどうすればよいですか? または、Mathematica でこの問題を別の方法で解決する必要がありますか?

4

2 に答える 2

3

この関数が意図したとおりに機能するかどうかはわかりませんが、次をSlotSequence使用して外側の関数の (##) をキャプチャできますWith

lift[g_] := Function[
  With[{fs = ##},
   Function[
    With[{args = ##},
     g @@ Map[(#[args]) &, List[fs]]]]]]

それで:

lift[f][a, b][c, d]

-> f[a[c, d], b[c, d]]

または、より読みやすい:

lift[g_] := Function[
  With[{fs = g[##]},
   Through[fs[##]] &]]
于 2012-12-11T08:51:15.517 に答える
2

ナイキは素晴らしい答えを出しました。これがそれを補完することを願っています。

を使用して一時関数を作成できますModule。これにより、パラメーター指定のパターンオプションの完全なセットが提供されます。たとえば、nikieの簡潔な方法を使用します。

lift1[g_] := Module[{fn}, fn[a__] := Through[g[a][##]] &; fn]

lift1[f][a, b][c, d]
f[a[c, d], b[c, d]]

この特定のケースでは、次のSubValuesようなルールを使用することもできます。

lift2[g_][h__] := Through[g[h][##]] &

lift2[f][a, b][c, d]
f[a[c, d], b[c, d]]

またはFunctionまったくなくても:

lift3[g_][h__][i__] := Through[ g[h][i] ]

lift3[f][a, b][c, d]
f[a[c, d], b[c, d]]
于 2012-12-12T01:24:00.543 に答える