我从库中看到了Curry函数的奇怪行为(roxygen)。这是一个最小的例子:
function [IDX, Me] = cvPfa(X, p, q)
[D, N] = size(X);
if ~exist('p', 'var') || isempty(p) || p == 0
p = D;
end
p = min(p, min(D, N-1));
if ~exist('q', 'var') || isempty(q)
q = p - 1;
end
%% PCA step
[U Me, Lambda] = cvPca(X, q);
%% cluter row vectors (q x D). not col
[Cl, Mu] = kmeans(U, p, 'emptyaction', 'singleton', 'distance', 'sqEuclidean');
%% find axis which are nearest to mean vector
IDX = logical(zeros(D,1));
for i = 1:p
Cli = find(Cl == i);
d = cvEucdist(Mu(i,:).', U(Cli,:).');
[mini, argmin] = min(d);
IDX(Cli(argmin)) = 1;
end
在这种情况下,呼叫
library(roxygen)
library(foreach)
f <- function(x,y,z) { return(x+y+z) }
fns <- list()
foreach(i=c(1:10)) %do% {
f[[i]] <- Curry(Curry(f,i),i)
}
返回11.我期待2。
有两个修正案对我没有任何意义 - 一个是平整循环,如
f[[1]](0)
有效。此外,在原始循环中放置单个函数评估也可以工作 - 如
fns <- list()
fns[[1]] <- Curry(Curry(f,1),1)
fns[[2]] <- Curry(Curry(f,2),2)
...
然后我们
fns <- list()
foreach(i=c(1:10)) %do% {
f[[i]] <- Curry(Curry(f,i),i)
f[[i]](27)
}
发生了什么?
答案 0 :(得分:3)
我认为Curry
为defined为
Curry<-function(FUN,...) {
dots<-list(...);
function(...) do.call(FUN,c(dots,list(...)))}
然后
f <- function(x,y,z) list(x,y,z)
fns<-vector("list",10)
for(i in 1:10) {fns[[i]]<-Curry(Curry(c,i),i)}
fns[[1]](0)
产量
[1] 10 1 0
显示直到完成循环后才评估f
的第一个参数。
这是由于懒惰的评估。
这里的罪魁祸首比Explain a lazy evaluation quirk更微妙,这就是为什么我在标记为副本时不知所措。
这里延迟的是FUN
CurryF<-function(FUN,...) {
force(FUN); #needed for nesting Curry
dots<-list(...);
function(...) do.call(FUN,c(dots,list(...)))}
现在再试一次
for(i in 1:10) {fns[[i]]<-CurryF(CurryF(c,i),i)}
fns[[1]](0)
预期结果
[1] 1 1 0