Kısa örnek. Bir fonksiyonun davranışını, farklı "spesifikasyonlar", f(spec)
ile test ederek araştırıyorum. Bir spekülasyonu el ile yazdım, spec1
ve üzerinde varyasyon olarak yeni özellikler oluşturuyorum. str(res1)
insan tarafından okunabilir olması için (... hayır <environment: ptr>
Temiz, basit işlev fabrikaları R
all.equal(spec1, res1)
ve/veyaidentical(spec1, res1)
make_spec
içinspec1 = list(fy = list(a = 1), fx = list(f1 = function(x) 10-x, f2 = function(x) 2-x)) make_spec = function(f = function(x) 10-x, xtheta = 2) list(fy = list(a = 1), fx = list(f1 = f, f2 = function(x) xtheta-x)) res1 = make_spec() # first problem: they don't match all.equal(res1,spec1) # [1] "Component “fx”: Component “f2”: target, current do not match when deparsed" #^this happens, even though... res1$fx$f2(4) == spec1$fx$f2(4) # TRUE # second problem: res1 is fugly res1 # $fy # $fy$a # [1] 1 # # # $fx # $fx$f1 # function (x) # 10 - x # <environment: 0x000000000f8f2e20> # # $fx$f2 # function (x) # xtheta - x # <environment: 0x000000000f8f2e20> str(res1) # even worse
Benim hedefler şunlardır: Bunu yapmak için, bir fonksiyon yazmaya karar Mümkünse
- veya
substitute
ve 'dan kaçınmak içinsubstitute
ikinci arg dışarı yazılmasını önlemek için
bu hedeflerin bazılarını veya tümünü elde etmek için deyimsel yolu var mı (aşağıda "tam" örnek bakınız)?
Tam örnek. Yukarıdaki örnek tamamen benim kullanma durumu kapsıyorsa yüzden burada ikincisiyse, emin değilim:
spec0 = list(
v_dist = list(
pdf = function(x) 1,
cdf = function(x) x,
q = function(x) x,
supp = c(0,1)
)
,
ucondv_dist = {
ucondv_dist = list()
ucondv_dist$condmean = function(v) 10-v
ucondv_dist$pdf = function(u,v) dnorm(u, ucondv_dist$condmean(v), 50)
ucondv_dist$cdf = function(u,v) pnorm(u, ucondv_dist$condmean(v), 50)
ucondv_dist
}
)
make_spec = function(ycondx_condmean = function(x) 10-x, ycondx_sd = 50){
s = substitute(list(
x_dist = list(
pdf = function(x) 1,
cdf = function(x) x,
q = function(x) x,
supp = c(0,1)
)
,
ycondx_dist = {
ycondx_dist = list()
ycondx_dist$condmean = ycondx_condmean
ycondx_dist$pdf = function(u,v) dnorm(u, ycondx_dist$condmean(v), ycondx_sd)
ycondx_dist$cdf = function(u,v) pnorm(u, ycondx_dist$condmean(v), ycondx_sd)
ycondx_dist
}
)
, list(ycondx_condmean=ycondx_condmean, ycondx_sd = ycondx_sd))
eval(s, .GlobalEnv)
}
res0 = make_spec()
Yan not. Burada "işlev fabrikası" nın doğru terim olup olmadığını bilmiyorum, çünkü bilgisayar bilimcisi değilim, ama ilgili görünüyor. Sadece a paragraph on the concept related to R'u buldum.
Aslında sadece Ar sevmiyorum ve gerçekten belki başka bir dilde, Scala veya erlang aradığınız görünür .. 'str' fonksiyonu oldukça karmaşık ama kesinlikle yeniden yazmak için bekliyoruz. Bu, makul bir SO sorusunun ne olacağı kadar büyük bir proje olurdu. 'Eval' ve 'substitute' kullanmadan dili programlamaya çalışmak fikri sapık görünüyor ve hiçbir şekilde haklı görülemiyor. –
@ 42- Geri bildirim için teşekkürler. Eh, 'eval' ve 'substitute' kaçınarak öncelikleri listemde düşük, ama ben sadece aptalca onlardan kaçınarak bir şekilde bakan, bunu bilmek isterdim. – Frank
bölüm 1'e erişebilirsiniz (yalnızca bir işlevden daha fazlasını döndürdüğünüzden), "kitaplık (pryr)", "res1 $ fx <- gecikme (res1 $ fx, unenclose)", "all.equal (res1, spec1)) – Chris