KDB+/Q:表示可变数量参数的规范方法?
KDB+/Q: Canonical method to represent a variable number of arguments?
我正在尝试在 kdb+/q 中创建一个模拟函数,它可以有效地将给定函数替换为记录调用等的函数,即
wrap:{[otherFn;params]
// update called etc.
:otherFn[params]
}
// function that replaces target fn
someOtherFn :{show x};
// store reference etc.
// use set to replace function
`.extern.someFn set wrap[someOtherFn];
在这种情况下,.extern.someFn 应该替换为 someOtherFn,并且应该可以这样调用:
q) .extern.someFn[1];
1
这很好,但是当人们试图增加函数参数的数量时,即
q) .extern.someFn[1;3]; //
'rank
表示排名错误。
有人可以告诉我如何达到这种效果吗?谢谢
您收到排名错误,因为上面定义的 .extern.someFn 是单个变量的函数。如果你想将 .extern.someFn 应用于多个输入,你可以使用迭代器:
q).extern.someFn each 1 3;
编辑:您可能对以下内容感兴趣:
q)functionWrapper:{[f;args] f . args};
q)testFunction:{x*y};
q)wrappedFunction:functionWrapper[testFunction];
q)wrappedFunction[2 3]
6
注意:args 需要是一个列表。多个参数不以 semi-colons 分隔。在混合列表的一般情况下,以 args:(arg1;arg2;...)
的形式指定 args
做这样的事情有几个(可以说是有效的*)理由。有一天我会在 q
中写一个 printf 替换
最简单的方法是将两个技巧与组合和入伍相结合。
首先入伍的是varadic:
enlist[1;2]
1 2
然后可以使用组合将函数组合在一起。我认为最接近您想要的是:
makeWrapFunc:{[f] (
callerfunc:{[f;params] f . params}f;
'[callerfunc;enlist]
}
现在,无论包装函数的级别如何,enlist 都会在应用之前为您将这些参数捆绑到一个列表中。
出于几乎相同的目的,我在下面的代码中使用了这个技巧。在我的例子中,我想通过现有函数和替换函数 运行 一些输入,并记录输出以供以后比较。
https://github.com/darrenarmstrong85/scientist/blob/master/lib/init.q#L97
有一些方法可以通过检查包装函数的参数数量并使用 null 进行绑定来将其扩展为部分应用程序,但我将把它留作 reader 的练习:-)
* 可以说这也是调试的噩梦。警告开发者。
我正在尝试在 kdb+/q 中创建一个模拟函数,它可以有效地将给定函数替换为记录调用等的函数,即
wrap:{[otherFn;params]
// update called etc.
:otherFn[params]
}
// function that replaces target fn
someOtherFn :{show x};
// store reference etc.
// use set to replace function
`.extern.someFn set wrap[someOtherFn];
在这种情况下,.extern.someFn 应该替换为 someOtherFn,并且应该可以这样调用:
q) .extern.someFn[1];
1
这很好,但是当人们试图增加函数参数的数量时,即
q) .extern.someFn[1;3]; //
'rank
表示排名错误。 有人可以告诉我如何达到这种效果吗?谢谢
您收到排名错误,因为上面定义的 .extern.someFn 是单个变量的函数。如果你想将 .extern.someFn 应用于多个输入,你可以使用迭代器:
q).extern.someFn each 1 3;
编辑:您可能对以下内容感兴趣:
q)functionWrapper:{[f;args] f . args};
q)testFunction:{x*y};
q)wrappedFunction:functionWrapper[testFunction];
q)wrappedFunction[2 3]
6
注意:args 需要是一个列表。多个参数不以 semi-colons 分隔。在混合列表的一般情况下,以 args:(arg1;arg2;...)
做这样的事情有几个(可以说是有效的*)理由。有一天我会在 q
中写一个 printf 替换最简单的方法是将两个技巧与组合和入伍相结合。
首先入伍的是varadic:
enlist[1;2]
1 2
然后可以使用组合将函数组合在一起。我认为最接近您想要的是:
makeWrapFunc:{[f] (
callerfunc:{[f;params] f . params}f;
'[callerfunc;enlist]
}
现在,无论包装函数的级别如何,enlist 都会在应用之前为您将这些参数捆绑到一个列表中。
出于几乎相同的目的,我在下面的代码中使用了这个技巧。在我的例子中,我想通过现有函数和替换函数 运行 一些输入,并记录输出以供以后比较。 https://github.com/darrenarmstrong85/scientist/blob/master/lib/init.q#L97
有一些方法可以通过检查包装函数的参数数量并使用 null 进行绑定来将其扩展为部分应用程序,但我将把它留作 reader 的练习:-)
* 可以说这也是调试的噩梦。警告开发者。