我正在尝试将以下方案代码翻译成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中以另一种方式解决这个问题吗?
答案 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)
您可以使用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]]