purrr中嵌套partial时.first=FALSE的作用歧义问题问询
解惑:
partial(partial, .first = FALSE)中.first的作用 嘿,这个问题真的戳中了purrr::partial里一个容易混淆的细节!我当初第一次折腾偏函数的时候也纠结过这个点,咱们一步步理清楚:
首先明确.first = FALSE的本质
.first是purrr::partial本身的控制参数,它不是给你最终生成的偏函数用的,而是用来告诉partial:「你生成偏函数的时候,怎么安排参数的顺序和匹配规则?」
具体来说:
- 默认
.first = TRUE:生成的偏函数会把原函数中未被你预先填充的参数,按原函数的顺序显式列在参数列表的开头,你填充的参数会作为“隐式预设值”藏在后面。 .first = FALSE:生成的偏函数会把你预先填充的参数作为默认参数放在列表末尾,未填充的参数则通过...来匹配——调用这个偏函数时,位置参数会优先按原函数的顺序匹配那些未被填充的参数。
你的backwards_partial到底做了什么?
你写的backwards_partial <- partial(partial, .first = FALSE),本质是创建了一个「预设了.first = FALSE的partial变体」。每次你用backwards_partial生成偏函数时,它都会自动给底层的partial传入.first = FALSE参数,相当于帮你省去了每次写partial(..., .first = FALSE)的重复代码。
用代码对比看区别
咱们用一个实际的函数来演示,更直观:
library(purrr) # 定义一个原函数 calc_total <- function(price, tax_rate, discount) { price * (1 + tax_rate) * (1 - discount) }
普通partial(默认.first = TRUE)
# 预先填充税率为0.1 calc_with_tax <- partial(calc_total, tax_rate = 0.1) # 看参数列表:未填充的price和discount被显式列在开头 args(calc_with_tax) #> function (price, discount, ...) #> NULL # 调用时,位置参数按显式列表的顺序匹配 calc_with_tax(100, 0.2) #> [1] 88 # 计算逻辑:100*(1+0.1)*(1-0.2)
用backwards_partial(预设.first = FALSE)
# 你的自定义偏函数生成器 backwards_partial <- partial(partial, .first = FALSE) # 同样预先填充税率为0.1 calc_with_tax_backwards <- backwards_partial(calc_total, tax_rate = 0.1) # 看参数列表:填充的tax_rate作为默认参数放在末尾,未填充的参数用...代替 args(calc_with_tax_backwards) #> function (..., tax_rate = 0.1) #> NULL # 调用时,位置参数依然按原函数的顺序匹配未填充的参数(price → discount) calc_with_tax_backwards(100, 0.2) #> [1] 88 # 和上面结果一致,但参数列表结构完全不同
什么时候这个区别会影响使用?
最明显的场景是当你需要给生成的偏函数传混合位置参数和命名参数时:
- 用默认
.first = TRUE生成的偏函数,必须按显式列出的参数顺序传位置参数; - 用
.first = FALSE生成的偏函数,位置参数永远遵循原函数的顺序,同时你还可以在末尾用命名参数覆盖预设值(比如calc_with_tax_backwards(100, 0.2, tax_rate = 0.05)会把税率改成0.05)。
总结你的疑问
你写的backwards_partial是完全符合预期的:
.first = FALSE不是作为输出偏函数的默认参数,而是作为调用底层partial时的控制参数;- 它的作用是让生成的偏函数把你预先填充的参数移到参数列表末尾,同时保留原函数的位置参数匹配顺序。
内容的提问来源于stack exchange,提问作者sgp667
相关产品推荐
相关产品推荐

