Труба с дополнительными аргументами - PullRequest
2 голосов
/ 02 мая 2020

Я читал в нескольких местах, что каналы в Юлии работают только с функциями, которые принимают только один аргумент. Это неправда, так как я могу сделать следующее:

function power(a, b = 2) a^b end
3 |> power
> 9

и все работает нормально.

Однако я не могу полностью разобраться с трубой. Например, почему это не работает? :

3 |> power()
> MethodError: no method matching power()

То, что я на самом деле хотел бы сделать, - это использовать канал и определить дополнительные аргументы, например, ключевые аргументы, чтобы на самом деле было ясно, какой аргумент передавать при передаче (а именно, единственный позиционный):

function power(a; b = 2) a^b end
3 |> power(b = 3)

Есть ли способ сделать что-то подобное?


Я знаю, что могу обойтись с пакетом Pipe, но, честно говоря, это выглядит как неуклюже написать @pipe в начале половины строк.

В R пакет magritrr имеет убедительные логики c (по моему мнению): он проходит то, что осталось от канала, по умолчанию в качестве первого аргумента функции справа - я ищу что-то похожее.

1 Ответ

4 голосов
/ 02 мая 2020

power, как определено в первом фрагменте, имеет два метода. Один с одним аргументом, один с двумя. Таким образом, пункт о |>, работающем только с методами с одним аргументом, остается в силе.

То, что вы хотите сделать, называется «частичным применением» и очень часто встречается в функциональных языках. Вы всегда можете написать

3 |> (a -> power(a, 3))

, но это быстро становится неуклюжим. Другие языки имеют синтаксис, такой как power(%1, 3), для обозначения этой лямбды. Есть обсуждение , чтобы добавить что-то похожее на Джулию, но это трудно понять правильно. Pipe - это именно то исправление, основанное на макросах.

Если у вас есть контроль над определенным методом, вы также можете реализовать методы с интерфейсом, который возвращает частично примененные версии, как вам нравится - многие предикаты в Base сделайте это уже, например, ==(1). Есть также опция Base.Fix2(power, 3), но это не совсем улучшение, если вы спросите меня (кроме, может быть, лучше, чем компилятор).

И обратите внимание, что magrittr s трубы также "макро" основанное . Разница в том, что передача аргумента в R намного сложнее, и вы не можете видеть снаружи, используется ли аргумент как значение или как выражение (по сути, R передает thunk, содержащий выражение и указатель на родительскую среду). и автоматически оценивает и кэширует его, если вы используете его в качестве значения; см. substitute)

...