Mathematica嵌套匿名变量Arity函数

时间:2012-12-11 08:27:44

标签: wolfram-mathematica anonymous-function arity

我正在尝试将以下方案代码翻译成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的“参数规范”应该是“符号或符号列表”。我知道我可以使用()&样式的匿名函数并使用##来获取所有参数,但问题是当我嵌套其中两个匿名函数时,我失去了访问外部参数的能力从内在的功能。

如何使用变量arity(和命名参数)编写匿名函数?或者我应该在Mathematica中以另一种方式解决这个问题吗?

2 个答案:

答案 0 :(得分: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[##]] &]]

答案 1 :(得分:2)

nikie给出了一个很好的答案。我希望这个补充它。

您可以使用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]]