Вы можете проверить реализацию magrittr , но, если честно, код довольно сложный, поскольку он делает намного больше.
Проще говоря, для поддержки семантики, которую вы хотите, чтобы вынеобходимо извлечь неоцененную RHS выражения и вставить в нее неоцененную LHS перед его оценкой.
Выражение вызова функции - это список, в котором имя функции является ее первым элементом, а остальные аргументы -последующие элементы.Поэтому вам нужно вставить значение LHS в этот список на второй позиции.
Затем вам нужно превратить полученный список обратно в вызов - as.call
делает это:
`%>%` = function (lhs, rhs) {
lhs = substitute(lhs)
rhs = substitute(rhs)
if (is.name(rhs)) {
do.call(as.character(rhs), list(lhs))
} else if (is.call(rhs)) {
rhs = as.list(rhs)
call = as.call(c(rhs[[1L]], list(lhs), rhs[-1L]))
eval.parent(call)
} else {
stop('Unsupported RHS')
}
}
Помните, что, поскольку эта реализация вставляет неоцененный LHS в вызов RHS, цепной конвейер будет оцениваться справа налево.То есть этот
(1 : 5) %>% sapply(`*`, 2) %>% sum()
будет преобразован в следующее:
sum(sapply((1: 5), `*`, 2))
до оценки любого компонента.